src/joepack.cpp

Go to the documentation of this file.
00001 #include "model.h"
00002 #include "joepack.h"
00003 
00004 #define JPKVERSION "JPK01.00"
00005 
00006 #define VERBOSE false
00007 
00008 #define DPRINT(text) {if (VERBOSE) cout << text << endl;}
00009 
00010 bool JOEPACK::LoadPack(string fn)
00011 {
00012         ClosePack();
00013         
00014         f = fopen(fn.c_str(), "rb");
00015         
00016         if (f)
00017         {
00018                 packpath = utility.GetPathFromFilename(fn);
00019                 
00020                 //load header
00021                 string versionstr = JPKVERSION;
00022                 char versioncstr[versionstr.length()+1];
00023                 fread(versioncstr, 1, versionstr.length(), f);
00024                 versioncstr[versionstr.length()] = '\0';
00025                 string fversionstr = versioncstr;
00026                 if (versioncstr != versionstr)
00027                 {
00028                         //write out an error?
00029                         return false;
00030                 }
00031                 
00032                 unsigned int numobjs = 0;
00033                 fread(&numobjs, sizeof(unsigned int), 1, f);
00034                 numobjs = ENDIAN_SWAP_32(numobjs);
00035                 
00036                 DPRINT(numobjs << " objects");
00037                 
00038                 unsigned int maxstrlen = 0;
00039                 fread(&maxstrlen, sizeof(unsigned int), 1, f);
00040                 maxstrlen = ENDIAN_SWAP_32(maxstrlen);
00041                 
00042                 DPRINT(maxstrlen << " max string length");
00043                 
00044                 char fnch[maxstrlen+1];
00045                 
00046                 //load FAT
00047                 for (unsigned int i = 0; i < numobjs; i++)
00048                 {
00049                         JOEPACK_FADATA fa;
00050                         fread(&(fa.offset), 1, sizeof(unsigned int), f);
00051                         fa.offset = ENDIAN_SWAP_32(fa.offset);
00052                         fread(&(fa.length), 1, sizeof(unsigned int), f);
00053                         fa.length = ENDIAN_SWAP_32(fa.length);
00054                         fread(fnch, 1, maxstrlen, f);
00055                         fnch[maxstrlen] = '\0';
00056                         string filename = fnch;
00057                         fat[filename] = fa;
00058                         
00059                         DPRINT(filename << ": offest " << fa.offset << " length " << fa.length);
00060                 }
00061                 
00062                 return true;
00063         }
00064         else
00065         {
00066                 //write an error?
00067                 return false;
00068         }
00069 }
00070 
00071 void JOEPACK::ClosePack()
00072 {
00073         Pack_fclose();
00074         fat.clear();
00075         if (f != NULL)
00076         {
00077                 fclose(f);
00078                 f = NULL;
00079         }
00080         packpath.clear();
00081 }
00082 
00083 void JOEPACK::Pack_fclose()
00084 {
00085         curfa = NULL;
00086 }
00087 
00088 bool JOEPACK::Pack_fopen(string fn)
00089 {
00090         if (fn.find(packpath, 0) < fn.length())
00091         {
00092                 string newfn = fn.substr(packpath.length()+1);
00093                 DPRINT(fn << " -> " << newfn);
00094                 fn = newfn;
00095         }
00096         
00097         DPRINT("Opening " << fn << " by seeking to " << fat[fn].offset);
00098         
00099         if (fat[fn].offset == 0)
00100         {
00101                 curfa = NULL;
00102                 //write an error?
00103                 return false;
00104         }
00105         else
00106         {
00107                 curfa = &(fat[fn]);
00108                 fseek(f, curfa->offset, SEEK_SET);
00109                 return true;
00110         }
00111 }
00112 
00113 int JOEPACK::Pack_fread(void * buffer, unsigned int size, unsigned int count)
00114 {
00115         if (curfa != NULL)
00116         {
00117                 unsigned int abspos = ftell(f);
00118                 assert(abspos >= curfa->offset);
00119                 unsigned int relpos = abspos - curfa->offset;
00120                 //DPRINT("relpos: " << relpos);
00121                 assert(curfa->length >= relpos);
00122                 unsigned int fileleft = curfa->length - relpos;
00123                 unsigned int requestedread = size*count;
00124                 
00125                 if (requestedread > fileleft)
00126                 {
00127                         //overflow
00128                         requestedread = fileleft;
00129                 }
00130                 
00131                 DPRINT("JOEPACK fread: " << abspos << "," << relpos << "," << fileleft << "," << requestedread);
00132                 
00133                 return fread(buffer, 1, requestedread, f);
00134         }
00135         else
00136         {
00137                 //write error?
00138                 return 0;
00139         }
00140 }

Generated on Thu Oct 19 04:05:53 2006 by  doxygen 1.4.6