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
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
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
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
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
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
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
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
00138 return 0;
00139 }
00140 }