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
00165 bool ans=checkInc(res,*buf,*len,msg);
00166 va_end(al);
00167 return ans;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180