Adonthell 0.4
fileops.cc
Go to the documentation of this file.
00001 /*
00002    $Id: fileops.cc,v 1.13 2003/01/24 22:15:43 ksterker Exp $
00003 
00004    Copyright (C) 1999/2000/2001/2002/2003 Alexandre Courbot
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 
00016 
00017 /**
00018  * @file   fileops.cc
00019  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
00020  * 
00021  * @brief  Defines the igzstream, ogzstream and fileops classes.
00022  * 
00023  */
00024 
00025 #include <stdio.h>
00026 #include <iostream>
00027 #include <SDL/SDL_endian.h>
00028 #include "fileops.h"
00029 
00030 
00031 using namespace std;
00032 
00033 
00034 gz_file::gz_file ()
00035 {
00036     opened = false;
00037 }
00038 
00039 gz_file::gz_file (const string & fname, gz_type t)
00040 {
00041     opened = false;
00042     open (fname, t);
00043 }
00044 
00045 gz_file::~gz_file ()
00046 {
00047     if (is_open ()) gzclose (file);
00048 }
00049 
00050 bool gz_file::open (const string & fname, gz_type t)
00051 {
00052     if (t == READ) file = gzopen (fname.c_str (),"rb6");
00053     else file = gzopen (fname.c_str (),"wb6");
00054     if (!file) return false;
00055     opened = true;
00056     return true;
00057 }
00058 
00059 void gz_file::close ()
00060 {
00061     if (is_open ()) gzclose (file);
00062     opened = false;
00063 }
00064 
00065 igzstream::igzstream () : gz_file ()
00066 {
00067 }
00068 
00069 igzstream::igzstream (const string & fname) : gz_file (fname, READ)
00070 {
00071 }
00072 
00073 igzstream::~igzstream ()
00074 {
00075 }
00076 
00077 bool igzstream::open (const string & fname)
00078 {
00079     return gz_file::open (fname, READ);
00080 }
00081 
00082 /// Reads a boolean.
00083 bool& operator << (bool& n, igzstream& gfile)
00084 {
00085     u_int8 b;
00086     gzread (gfile.file, &b, sizeof (b));
00087     return (n = b);
00088 }
00089 
00090 /// Reads a boolean.
00091 bool igzstream::get_bool ()
00092 {
00093     u_int8 b;
00094     gzread (file, &b, sizeof (b));
00095     return b;
00096 }
00097 
00098 /// Reads a char.
00099 char& operator << (char& n, igzstream& gfile)
00100 {
00101     gzread (gfile.file, &n, sizeof (n));
00102     return n;
00103 }
00104 
00105 /// Read a block of size chars
00106 void igzstream::get_block (void * to, u_int32 size)
00107 {
00108     gzread (file, to, size); 
00109 }
00110 
00111 /// Reads a u_int8.
00112 u_int8& operator << (u_int8& n, igzstream& gfile)
00113 {
00114     gzread(gfile.file, &n, sizeof (n));
00115     return n;
00116 }
00117 
00118 /// Reads a u_int8.
00119 u_int8 igzstream::get_uint8 ()
00120 {
00121     u_int8 n;
00122     gzread (file, &n, sizeof (n));
00123     return n;
00124 }
00125 
00126 /// Reads a s_int8.
00127 s_int8& operator << (s_int8& n, igzstream& gfile)
00128 {
00129     gzread(gfile.file, &n, sizeof (n));
00130     return n;
00131 }
00132 
00133 /// Reads a s_int8.
00134 s_int8 igzstream::get_sint8 ()
00135 {
00136     s_int8 n;
00137     gzread (file, &n, sizeof (n));
00138     return n;
00139 }
00140 
00141 /// Reads a u_int16.
00142 u_int16& operator << (u_int16& n, igzstream& gfile)
00143 {
00144     gzread(gfile.file, &n, sizeof (n));
00145     n = SDL_SwapLE16(n);
00146     return n;
00147 }
00148 
00149 /// Reads a u_int16.
00150 u_int16 igzstream::get_uint16 ()
00151 {
00152     u_int16 n;
00153     gzread (file, &n, sizeof (n));
00154     return SDL_SwapLE16(n);
00155 }
00156 
00157 /// Reads a s_int16.
00158 s_int16& operator << (s_int16& n, igzstream& gfile)
00159 {
00160     gzread(gfile.file, &n, sizeof (n));
00161     n = SDL_SwapLE16(n);
00162     return n;
00163 }
00164 
00165 /// Reads a s_int16.
00166 s_int16 igzstream::get_sint16 ()
00167 {
00168     s_int16 n;
00169     gzread (file, &n, sizeof (n));
00170     return SDL_SwapLE16(n);
00171 }
00172 
00173 /// Reads a u_int32.
00174 u_int32& operator << (u_int32& n, igzstream& gfile)
00175 {
00176     gzread(gfile.file, &n, sizeof (n));
00177     n = SDL_SwapLE32(n);
00178     return n;
00179 }
00180 
00181 /// Reads a u_int32.
00182 u_int32 igzstream::get_uint32 ()
00183 {
00184     u_int32 n;
00185     gzread (file, &n, sizeof (n));
00186     return SDL_SwapLE32(n);
00187 }
00188 
00189 /// Reads a s_int32.
00190 s_int32& operator << (s_int32& n, igzstream& gfile)
00191 {
00192     gzread(gfile.file, &n, sizeof (n));
00193     n = SDL_SwapLE32(n);
00194     return n;
00195 }
00196 
00197 /// Reads a s_int32.
00198 s_int32 igzstream::get_sint32 ()
00199 {
00200     s_int32 n;
00201     gzread (file, &n, sizeof (n));
00202     return SDL_SwapLE32(n);
00203 }
00204 
00205 /// Reads a string.
00206 string& operator << (string& s, igzstream& gfile)
00207 {
00208     u_int16 strl;
00209     char c;
00210     s = ""; 
00211     strl << gfile;
00212     while (strl)
00213     {
00214     c << gfile;
00215     s += c;
00216     strl --;
00217     }
00218     return s;
00219 }
00220 
00221 /// Reads a string.
00222 string igzstream::get_string ()
00223 {
00224     string s;
00225     s << *this;
00226     return s;
00227 }
00228 
00229 /// Reads a float.
00230 float& operator << (float& f, igzstream& gfile)
00231 {
00232     string sf;
00233     sf << gfile;
00234     
00235     // floats saved as strings to remain independent of architecture
00236     sscanf (sf.c_str (), "%f", &f);
00237     
00238     return f;
00239 }
00240 
00241 /// Reads a float.
00242 float igzstream::get_float ()
00243 {
00244     float f;
00245     f << *this;
00246     return f;
00247 }
00248 
00249 
00250 ogzstream::ogzstream () : gz_file ()
00251 {
00252 }
00253 
00254 ogzstream::ogzstream (const string & fname) : gz_file (fname, WRITE)
00255 {
00256 }
00257 
00258 ogzstream::~ogzstream ()
00259 {
00260 }
00261 
00262 bool ogzstream::open (const string & fname)
00263 {
00264     return gz_file::open (fname, WRITE);
00265 }
00266 
00267 void ogzstream::put_block (void * to, u_int32 size)
00268 {
00269     gzwrite (file, to, size); 
00270 }
00271 
00272 /// Writes a boolean.
00273 const bool& operator >> (const bool& n, ogzstream& gfile)
00274 {
00275     u_int8 b = n;
00276     gzwrite (gfile.file, &b, sizeof (b));
00277     return n;
00278 }
00279 
00280 /// Writes a char.
00281 const char& operator >> (const char& n, ogzstream& gfile)
00282 {
00283     gzwrite (gfile.file, (char *) &n, sizeof (n));
00284     return n;
00285 }
00286 
00287 /// Writes a u_int8.
00288 const u_int8& operator >> (const u_int8& n, ogzstream& gfile)
00289 {
00290     gzwrite(gfile.file, (u_int8 *) &n, sizeof (n));
00291     return n;
00292 }
00293 
00294 /// Writes a s_int8.
00295 const s_int8& operator >> (const s_int8& n, ogzstream& gfile)
00296 {
00297     gzwrite(gfile.file, (s_int8 *) &n, sizeof (n));
00298     return n;
00299 }
00300 
00301 /// Writes a u_int16.
00302 const u_int16& operator >> (const u_int16& n, ogzstream& gfile)
00303 {
00304     u_int16 s = SDL_SwapLE16(n);
00305     gzwrite(gfile.file, (u_int16 *) &s, sizeof (n));
00306     return n;
00307 }
00308 
00309 /// Writes a s_int16.
00310 const s_int16& operator >> (const s_int16& n, ogzstream& gfile)
00311 {
00312     s_int16 s = SDL_SwapLE16(n);
00313     gzwrite(gfile.file, (s_int16 *) &s, sizeof (n));
00314     return n;
00315 }
00316 
00317 /// Writes a u_int32.
00318 const u_int32& operator >> (const u_int32& n, ogzstream& gfile)
00319 {
00320     u_int32 s = SDL_SwapLE32(n);
00321     gzwrite(gfile.file, (u_int32 *) &s, sizeof (n));
00322     return n;
00323 }
00324 
00325 /// Writes a s_int32.
00326 const s_int32& operator >> (const s_int32& n, ogzstream& gfile)
00327 {
00328     s_int32 s = SDL_SwapLE32(n);
00329     gzwrite(gfile.file, (s_int32 *) &s, sizeof (n));
00330     return n;
00331 }
00332 
00333 /// Writes a string.
00334 string& operator >> (const string& s, ogzstream& gfile)
00335 {
00336     u_int16 strl = s.length ();
00337     string::iterator i; 
00338     strl >>  gfile;
00339     
00340     for (i = ((string&) s).begin (); i != ((string&) s).end (); i++) 
00341         (*i) >>  gfile;
00342     return (string&) s;
00343 }
00344 
00345 /// Writes a float.
00346 const float& operator >> (const float& f, ogzstream& gfile)
00347 {
00348     char sf[16];
00349     
00350     // floats saved as strings to remain independent of architecture
00351     snprintf (sf, 16, "%f", f);
00352     sf >> gfile;
00353     
00354     return f;
00355 }
00356 
00357 void fileops::put_version (ogzstream& file, u_int16 version)
00358 {
00359     char c = 'v'; 
00360     c >> file;
00361     version >> file; 
00362 }
00363 
00364 // read version info from file and check whether we can handle it
00365 bool fileops::get_version (igzstream& file, u_int16 min, u_int16 max, string name)
00366 {
00367     char vinfo;
00368     u_int16 version;
00369 
00370     vinfo << file;
00371 
00372     if (name == "") name = "<unknown>";
00373 
00374     // file contains no version info
00375     if (vinfo != 'v')
00376     {
00377         cerr << "Version information missing in file \"" << name << endl;
00378         cerr << "You should get a more recent data package.\n";
00379         return false;
00380     }
00381     
00382     // check whether file has the version we expect
00383     version << file;
00384 
00385     if (version < min || version > max)
00386     {
00387         cerr << "File \"" << name << "\" has\nversion number " << version << ", ";
00388         cerr <<  "but I was expecting " << min << " <= version <= " << max << endl;
00389     
00390         // file is newer than code
00391         if (version > max)
00392             cerr << "You should get an up-to-date version of this program.\n\n";
00393         // file is older than code
00394         else
00395             cerr << "You should probably get a more recent data package.\n";
00396 
00397         return false;
00398     } 
00399     return true;
00400 }