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=0;
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 unsigned int LoadSave::saveCreator(const char* creator, FILE* f) const throw() {
00070   return encode(creator,f);
00071 }
00072 
00073 unsigned int LoadSave::loadFile(const char* file) {
00074   int err;
00075   std::cout << "Loading: " << file << std::endl;
00076   FILE* f = fopen(file,"r");
00077   if(f==NULL) {
00078     std::cout << "*** WARNING could not open file for loading \"" << file << "\"" << std::endl;
00079     return 0;
00080   }
00081   unsigned int sz = loadFileStream(f,file);
00082   if(sz==0)
00083     std::cout << "*** WARNING loading of " << file << " failed " << std::endl;
00084   err=fclose(f);
00085   if(err!=0) {
00086     std::cout << "*** WARNING error " << err << " while closing " << file << std::endl;
00087     return 0;
00088   }
00089   return sz;
00090 }
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, const char* filename) {
00112   struct stat sb;
00113   int err=fstat(fileno(f),&sb);
00114   if(err!=0) {
00115     if (filename)
00116       std::cerr << "File: " << filename << std::endl;
00117     perror("fstat failed in LoadSave::loadFileStream()");
00118     return 0;
00119   }
00120   long origpos=ftell(f);
00121   if(origpos<0) {
00122     if (filename)
00123       std::cerr << "File: " << filename << std::endl;
00124     perror("ftell failed in LoadSave::loadFileStream()");
00125     return 0;
00126   }
00127   size_t cap=static_cast<size_t>(sb.st_size-origpos);
00128   char * buf = NULL;
00129   try { buf=new char[cap]; } catch(...) {}
00130   if(buf==NULL) {
00131     if (filename)
00132       std::cerr << "File: " << filename << std::endl;
00133     std::cout << "*** WARNING could not allocate " << cap << "+ bytes for loadFile";
00134     return 0;
00135   }
00136   unsigned int read=fread(buf,1,cap,f);
00137   unsigned int pos=0;
00138   while(cap!=pos+read) {
00139     pos+=read;
00140     read=fread(&buf[pos],1,cap-pos,f);
00141   }
00142   unsigned int resp=loadBuffer(buf,cap);
00143   delete [] buf;
00144   if(resp!=cap)
00145     fseek(f,origpos+resp,SEEK_SET);
00146   return resp;
00147 }
00148 unsigned int LoadSave::saveFileStream(FILE* f) const {
00149   unsigned int sz=getBinSize();
00150   char * buf = new char[sz];
00151   if(buf==NULL) {
00152     std::cout << "*** ERROR could not allocate " << sz << " bytes for loadFile";
00153     return 0;
00154   }
00155   unsigned int resp=saveBuffer(buf,sz);
00156   if(resp==0) {
00157     std::cout << "*** WARNING saveBuffer (from saveFileStream) didn't write any data (possibly due to overflow or other error)" << std::endl;
00158   } else {
00159     size_t wrote = fwrite(buf,1,resp,f);
00160     if(wrote!=(size_t)resp)
00161       std::cout << "*** ERROR short write (wrote " << wrote << ", expected " << resp << ")" << std::endl;
00162   }
00163   delete [] buf;
00164   return resp;
00165 }
00166 unsigned int LoadSave::saveStream(std::ostream& os) const {
00167   unsigned int sz=getBinSize();
00168   char * buf = new char[sz];
00169   if(buf==NULL) {
00170     std::cout << "*** ERROR could not allocate " << sz << " bytes for loadFile";
00171     return 0;
00172   }
00173   unsigned int resp=saveBuffer(buf,sz);
00174   if(resp==0) {
00175     std::cout << "*** WARNING saveBuffer (from saveStream) didn't write any data (possibly due to overflow or other error)" << std::endl;
00176   } else {
00177     os.write(buf,resp);
00178     if(!os)
00179       std::cout << "*** ERROR saveStream's output stream reported bad write" << std::endl;
00180     resp=0;
00181   }
00182   delete [] buf;
00183   return resp;
00184 }
00185 
00186 
00187 unsigned int LoadSave::LoadFile(const char* filename) { return loadFile(filename); }
00188 unsigned int LoadSave::SaveFile(const char* filename) const { return saveFile(filename); }
00189 bool LoadSave::chkAdvance(int res, const char** buf, unsigned int* len, const char* msg, ...) {
00190   va_list al;
00191   va_start(al,msg);
00192   //todo
00193   bool ans=checkInc(res,*buf,*len,"%s",msg);
00194   va_end(al);
00195   return ans;
00196 }
00197 
00198 /*! @file
00199  * @brief Implements LoadSave, inherit from this to use a standard interface for loading and saving
00200  * @author ejt (Creator)
00201  */
00202 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:43 2016 by Doxygen 1.6.3