Adonthell 0.4
|
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 }