Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

LoadSave.cc

Go to the documentation of this file.
00001 #include "LoadSave.h"
00002 #include <iostream>
00003 #include <string.h>
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 
00007 LoadSave::~LoadSave() {}
00008 
00009 unsigned int LoadSave::checkCreator(const char* creator, const char buf[], unsigned int len, bool isLoading) const throw() {
00010   const char* type=buf+getSerializedSize<unsigned int>();
00011   if(strcmp(type,creator)!=0) {
00012     if(isLoading)
00013       std::cout << "*** WARNING " << creator << "::loadBuffer - corruption detected, got '" << std::string(type) << "'" << std::endl;
00014     return 0;
00015   }
00016   unsigned int sz;
00017   decode(sz,buf,len);
00018   return sz+stringpad;
00019 }
00020 bool LoadSave::checkCreatorInc(const char* creator, const char*& buf, unsigned int& len, bool isLoading) const throw() {
00021   if(unsigned int used=checkCreator(creator,buf,len,isLoading)) { buf+=used; len-=used; return true; }
00022   else return false;
00023 }
00024 void LoadSave::checkCreatorIncT(const char* creator, const char*& buf, unsigned int& len, bool isLoading) const throw(std::runtime_error) {
00025   if(checkCreatorInc(creator,buf,len,isLoading))
00026     return;
00027   std::string err="incorrect creator code: ";
00028   err+=creator;
00029   err+=" vs ";
00030   err+=std::string(buf,strlen(creator));
00031   throw std::runtime_error(err);
00032 }
00033 
00034 unsigned int LoadSave::checkCreator(const char* creator, FILE* f, bool isLoading) const throw() {
00035   unsigned int sz=0,last;
00036   unsigned int origpos=ftell(f);
00037   char* type=NULL;
00038   if(!(last=decode(type,f))) {
00039     fseek(f,origpos,SEEK_SET);
00040     return 0;
00041   } else
00042     sz+=last;
00043   if(strncmp(type,creator,strlen(creator))!=0) {
00044     if(isLoading)
00045       std::cout << "*** WARNING " << creator << "::loadBuffer - corruption detected" << std::endl;
00046     fseek(f,origpos,SEEK_SET);
00047     delete [] type; 
00048     return 0;
00049   }
00050   delete [] type; 
00051   return sz;
00052 }
00053 
00054 unsigned int LoadSave::saveCreator(const char* creator, char buf[], unsigned int len) const throw() {
00055   return encode(std::string(creator),buf,len);
00056 }
00057 bool LoadSave::saveCreatorInc(const char* creator, char*& buf, unsigned int& len) const throw() {
00058   if(unsigned int used=saveCreator(creator,buf,len)) { buf+=used; len-=used; return true; }
00059   else return false;
00060 }
00061 void LoadSave::saveCreatorIncT(const char* creator, char*& buf, unsigned int& len) const throw(std::runtime_error) {
00062   if(saveCreatorInc(creator,buf,len))
00063     return;
00064   std::string err="unable to save creator code: ";
00065   err+=creator;
00066   err+=" (ran out of space?)";
00067   throw std::runtime_error(err);
00068 }
00069 
00070 unsigned int LoadSave::saveCreator(const char* creator, FILE* f) const throw() {
00071   return encode(creator,f);
00072 }
00073 
00074 unsigned int LoadSave::loadFile(const char* file) {
00075   int err;
00076   std::cout << "Loading: " << file << std::endl;
00077   FILE* f = fopen(file,"r");
00078   if(f==NULL) {
00079     std::cout << "*** WARNING could not open file for loading \"" << file << "\"" << std::endl;
00080     return 0;
00081   }
00082   unsigned int sz = loadFileStream(f);
00083   if(sz==0)
00084     std::cout << "*** WARNING loading of " << file << " failed " << std::endl;
00085   err=fclose(f);
00086   if(err!=0) {
00087     std::cout << "*** WARNING error " << err << " while closing " << file << std::endl;
00088     return 0;
00089   }
00090   return sz;
00091 }
00092 unsigned int LoadSave::saveFile(const char* file) const {
00093   int err;
00094   std::cout << "Saving: " << file << std::endl;
00095   FILE* f = fopen(file,"w");
00096   if(f==NULL) {
00097     std::cout << "*** WARNING could not open file for saving \"" << file << "\"" << std::endl;
00098     return 0;
00099   }
00100   unsigned int sz = saveFileStream(f);
00101   if(sz==0)
00102     std::cout << "*** WARNING saving of " << file << " failed " << std::endl;
00103   err=fclose(f);
00104   if(err!=0) {
00105     std::cout << "*** WARNING error " << err << " while closing " << file << std::endl;
00106     return 0;
00107   }
00108   return sz;
00109 }
00110 
00111 unsigned int LoadSave::loadFileStream(FILE* f) {
00112   struct stat sb;
00113   int err=fstat(fileno(f),&sb);
00114   if(err!=0) {
00115     perror("fstat failed in LoadSave::loadFileStream()");
00116     return 0;
00117   }
00118   unsigned int origpos=ftell(f);
00119   unsigned int cap=sb.st_size-origpos;
00120   char * buf = NULL;
00121   try { buf=new char[cap]; } catch(...) {}
00122   if(buf==NULL) {
00123     std::cout << "*** WARNING could not allocate " << cap << "+ bytes for loadFile";
00124     return 0;
00125   }
00126   unsigned int read=fread(buf,1,cap,f);
00127   unsigned int pos=0;
00128   while(cap!=pos+read) {
00129     pos+=read;
00130     read=fread(&buf[pos],1,cap-pos,f);
00131   }
00132   unsigned int resp=loadBuffer(buf,cap);
00133   delete [] buf;
00134   if(resp!=cap)
00135     fseek(f,origpos+resp,SEEK_SET);
00136   return resp;
00137 }
00138 unsigned int LoadSave::saveFileStream(FILE* f) const {
00139   unsigned int sz=getBinSize();
00140   char * buf = new char[sz];
00141   memset(buf,0xF0,sz);
00142   if(buf==NULL) {
00143     std::cout << "*** WARNING could not allocate " << sz << " bytes for loadFile";
00144     return 0;
00145   }
00146   unsigned int resp=saveBuffer(buf,sz);
00147   if(resp==0) {
00148     std::cout << "*** WARNING saveBuffer didn't write any data (possibly due to overflow or other error)" << std::endl;
00149     fwrite(buf,1,sz,f);
00150   } else {
00151     unsigned int wrote=fwrite(buf,1,resp,f);
00152     if(wrote!=resp)
00153       std::cout << "*** WARNING short write (wrote " << wrote << ", expected " << resp << ")" << std::endl;
00154   }
00155   delete [] buf;
00156   return resp;
00157 }
00158 
00159 unsigned int LoadSave::LoadFile(const char* filename) { return loadFile(filename); }
00160 unsigned int LoadSave::SaveFile(const char* filename) const { return saveFile(filename); }
00161 bool LoadSave::chkAdvance(int res, const char** buf, unsigned int* len, const char* msg, ...) {
00162   va_list al;
00163   va_start(al,msg);
00164   //todo
00165   bool ans=checkInc(res,*buf,*len,msg);
00166   va_end(al);
00167   return ans;
00168 }
00169 
00170 /*! @file
00171  * @brief Implements LoadSave, inherit from this to use a standard interface for loading and saving
00172  * @author ejt (Creator)
00173  *
00174  * $Author: ejt $
00175  * $Name: tekkotsu-4_0 $
00176  * $Revision: 1.10 $
00177  * $State: Exp $
00178  * $Date: 2006/09/12 20:24:04 $
00179  */
00180 

Tekkotsu v4.0
Generated Thu Nov 22 00:54:53 2007 by Doxygen 1.5.4