author | ecalot
<ecalot> 2005-06-03 07:33:44 UTC |
committer | ecalot
<ecalot> 2005-06-03 07:33:44 UTC |
parent | 1369a75ad48ae9d9de2277e7688b174e254bb1d4 |
PR/src/include/dat.h | +9 | -1 |
PR/src/include/disk.h | +2 | -2 |
PR/src/lib/actions/classify.c | +5 | -2 |
PR/src/lib/layers/dat.c | +89 | -18 |
diff --git a/PR/src/include/dat.h b/PR/src/include/dat.h index 02fb013..7e395a5 100644 --- a/PR/src/include/dat.h +++ b/PR/src/include/dat.h @@ -36,7 +36,15 @@ dat.h: Princed Resources : DAT library headers #include "resources.h" -#define MAX_RES_COUNT 25000 +#define MAX_RES_COUNT 65000 + +typedef enum { + none=0, + pop1=1, + pop2=2 +} tPopVersion; + +tPopVersion mReadGetVersion(); #define PR_DAT_INCLUDE_DATREAD #define PR_DAT_INCLUDE_DATWRITE diff --git a/PR/src/include/disk.h b/PR/src/include/disk.h index 1b32fdf..780fb90 100644 --- a/PR/src/include/disk.h +++ b/PR/src/include/disk.h @@ -91,8 +91,8 @@ int recurseDirectory(const char* path,int recursive, void* pass, void (*function /* array2vars*/ -#define array2short(a) ((*(a)))+((*((a)+1))<<8) -#define array2long(a) ((*(a)))+((*((a)+1))<<8)+((*((a)+2))<<16)+((*((a)+3))<<24) +#define array2short(a) (((*(a)))+((*((a)+1))<<8)) +#define array2long(a) (((*(a)))+((*((a)+1))<<8)+((*((a)+2))<<16)+((*((a)+3))<<24)) #ifdef MACOS #define freadshort(var,file) macfreads ((var),file) diff --git a/PR/src/lib/actions/classify.c b/PR/src/lib/actions/classify.c index 15033b7..c5cdd94 100644 --- a/PR/src/lib/actions/classify.c +++ b/PR/src/lib/actions/classify.c @@ -43,7 +43,7 @@ tasks.c: Princed Resources : Classify a DAT file | Get the type of a DAT file | \***************************************************************/ -extern int pop1; +/*extern int pop1;*/ #define READ_ERROR {mReadCloseDatFile();return 0;} @@ -54,10 +54,13 @@ int prClassifyDat(const char* vFiledat) { unsigned long int size; int type=RES_TYPE_BINARY; unsigned short int numberOfItems; + tPopVersion popVersion; /* Initialize abstract variables to read this new DAT file */ if ((id=mReadBeginDatFile(&numberOfItems,vFiledat))) return id+1; /* -1 if not found or empty, 0 if invalid */ + popVersion=mReadGetVersion(); + /* main loop */ for (id=0,indexNumber=0;(indexNumber<numberOfItems)&&(type==RES_TYPE_BINARY);indexNumber++) { id=mReadFileInDatFile(indexNumber,&data,&size); @@ -68,7 +71,7 @@ int prClassifyDat(const char* vFiledat) { } mReadCloseDatFile(); - return pop1?type:(type+10); + return (popVersion==pop1)?type:(type+10); } typedef struct { diff --git a/PR/src/lib/layers/dat.c b/PR/src/lib/layers/dat.c index 57d05d9..40889af 100644 --- a/PR/src/lib/layers/dat.c +++ b/PR/src/lib/layers/dat.c @@ -47,7 +47,7 @@ dat.c: Princed Resources : DAT library char recordSize; int ofk=0; -int pop1; +tPopVersion popVersion; unsigned char* indexPointer; unsigned long int indexOffset; unsigned long int offset; @@ -55,6 +55,67 @@ unsigned short int indexSize; unsigned char* readDatFile; int readDatFileSize; +/* private functions */ + +tPopVersion detectPopVersion(int highArea,int highAreaSize) { + const unsigned char* cursor; + unsigned short numberOfRecords; + + /* create cursor */ + cursor=readDatFile+highArea; + + /* read number of records */ + numberOfRecords=array2short(cursor);cursor+=2; + + /* check pop1: if there are numberOfRecords records sized 8 and 2 bytes for the short numberOfRecords */ + if ((numberOfRecords*8+2)==highAreaSize) { + indexPointer=readDatFile+highArea; + indexSize=highAreaSize; + recordSize=8; + return pop1; + } + + /* check pop2: if there are numberOfRecords records sized 6 and 2 bytes for the short numberOfRecords */ + if ((numberOfRecords*6+2)>=highAreaSize) return none; + printf("pop2 detected with %d high sections\n",numberOfRecords); + recordSize=0; + for (;numberOfRecords;numberOfRecords--,cursor+=6) { + int startOfSection; + int endOfSection; + int sizeOfSection; + + /* calculate section size and offset */ + if (numberOfRecords==1) { /* the last section size is calculated using the highAreaSize */ + endOfSection=highAreaSize; + } else { + endOfSection=array2short(cursor+10); + } + startOfSection=array2short(cursor+4); + sizeOfSection=endOfSection-startOfSection; + + /* check section integrity */ + if (sizeOfSection<0) return none; + + printf("Section %c%c%c%c starts at %d, ends at %d and length %d\n",cursor[0],cursor[1],cursor[2],cursor[3],startOfSection,endOfSection,sizeOfSection); + + /* check for the PAHS section */ + if (!strncmp("PAHS",(char*)cursor,4)) { /* TODO: send to define */ + indexPointer=readDatFile+highArea+startOfSection; + indexSize=sizeOfSection; + recordSize=11; + } + + } + + return pop2; +} + +/* public functions */ + +tPopVersion mReadGetVersion() { + return popVersion; +} + void mReadCloseDatFile() { free(readDatFile); } @@ -72,32 +133,34 @@ int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){ /* Open file */ readDatFileSize=mLoadFileArray(vFiledat,&readDatFile); if (!readDatFileSize) return -2; - if (readDatFileSize<=6) {free(readDatFile);return -1;} + if (readDatFileSize<=6) { + free(readDatFile); + return -1; + } readDatFilePoint=readDatFile; - /* verify dat format */ + /* read header */ indexOffset=array2long(readDatFilePoint); readDatFilePoint+=4; indexSize=array2short(readDatFilePoint); + /* verify dat format: the index offset belongs to the file and the file size is the index size plus the index offset */ if ((indexOffset>readDatFileSize)&&((indexOffset+indexSize)!=readDatFileSize)) { free(readDatFile); return -1; /* this is not a valid prince dat file */ } - indexPointer=readDatFile+indexOffset; + /* read the high data to detect pop version and set up the indexPointer, indexSize and recordSize */ + popVersion=detectPopVersion(indexOffset,indexSize); + + /* pop version check */ + if (popVersion==none) return -1; + if (!recordSize) {*numberOfItems=0; return 0;} /* valid dat file without an index */ + + /* read numberOfItems */ *numberOfItems=array2short(indexPointer); indexPointer+=2; - pop1=(((*numberOfItems)*8+2)==indexSize); - - if (!pop1) { /* verify if pop2 */ - ofk=(*numberOfItems)*6+2+((*numberOfItems)-2)*13; - (*numberOfItems)=((indexSize-6-((*numberOfItems)*6)-(((*numberOfItems)-2)*13))/11); - } else { - ofk=0; - } - recordSize=pop1?8:11; return 0; } @@ -107,12 +170,20 @@ int mReadFileInDatFile(int k,unsigned char* *data,unsigned long int *size) { unsigned short int id; /* for each archived file the index is read */ - id= array2short(indexPointer+ofk+k*recordSize); - offset=array2long(indexPointer+ofk+k*recordSize+2); - *size= array2short(indexPointer+ofk+k*recordSize+6)+1; - if ((!pop1)&&(!(indexPointer[ofk+k*recordSize+8]==0x40)&&(!indexPointer[ofk+k*recordSize+9])&&(!indexPointer[ofk+k*recordSize+10]))) return -1; - if (offset+indexSize>readDatFileSize) return -1; + id= array2short(indexPointer+k*recordSize); + offset=array2long(indexPointer+k*recordSize+2); + *size= array2short(indexPointer+k*recordSize+6)+1; + + if ( /* pop2 integrity check */ + (popVersion==pop2) && + (!(indexPointer[k*recordSize+8]==0x40) && + (!indexPointer[k*recordSize+9]) && + (!indexPointer[k*recordSize+10]) + )) return -1; + + if (offset>indexOffset) return -1; /* a resourse offset is allways before the index offset */ *data=readDatFile+offset; + return ok?id:-1; }