#include #include #include typedef unsigned char byte; typedef struct{ byte ver; byte lastupd[3]; int headerlen; short data; byte res_a[2]; byte lastaction; byte encrypted; byte res_b[4]; byte res_c[8]; byte mdx; byte lang; byte res_d[2]; }dbfHeader; typedef struct dbfIDS dbfIDS; struct dbfIDS{ byte name[11]; byte type; int address; byte len; byte deccount; byte res_a[2]; byte wid; byte res_b[2]; byte flag; byte res_c[7]; byte index; dbfIDS *next;//LINKED LIST!!! }; typedef struct dbfROWS dbfROWS; struct dbfROWS{ byte * data; byte len; byte type; dbfROWS * next;//YES ANOTHER LINKED LIST*!!@#@# }; typedef struct{ dbfHeader header; }dbfFormat; inline void endian_swap32(int* x){ *x = (*x>>24)|(*x>>16)|(*x>>8)|(*x); } inline void endian_swap16(short* x){ *x = (*x>>8)|(*x); } void freelist(const void * list); //will need this to iterate through a linked list and free each one. void loadDBF(const char * filename,byte ** buffer,long * len); void getHeader(const dbfHeader * header,const byte * buffer); int getIDNames(dbfIDS ** list,const byte * buffer,const int start,const dbfHeader * length); void getRows(dbfROWS ** rows,dbfIDS * idList,byte * buffer,const int rowlen); int saveDBF(const char * filename,dbfFormat * updates); int main(int argc, char *argv[]) { byte * dbf = NULL; dbfIDS * idList = NULL; dbfROWS * rowList = NULL; dbfHeader dbf_header; long len = 0; int rowlen = 0; loadDBF("tests.dbf",&dbf,&len); if(dbf!=NULL){ printf("Loaded: %d bytes\n",len); getHeader(&dbf_header,dbf); rowlen = getIDNames(&idList,dbf,sizeof(dbfHeader),&dbf_header); getRows(&rowList,idList,dbf+dbf_header.data+1,rowlen+1); free(dbf); }else{ printf("Error?\n"); } system("PAUSE"); return 0; } void loadDBF(const char * filename,byte ** buffer, long * len){ FILE * desc = fopen(filename,"r+b"); long i = 0; if(desc!=NULL){ //File found... fseek(desc,0L,SEEK_END); *len = ftell(desc); if(*len>30){ //check to see if it even is somewhat of file for a dbf header. *buffer = (byte*)malloc(sizeof(byte)*(*len)); if(*buffer!=NULL){ rewind(desc); if(!fread(*buffer,*len,sizeof(byte),desc)>0){ perror("fread"); } //all is well now return non-null buffer :D fclose(desc); }else{ //if we get here really? why even let the application run... printf("Not enough memory...shutting down...\n"); } }else{ printf("Not enough information to be a dbf file...\n"); fclose(desc); } }else{ perror("fopen"); } } void getHeader(const dbfHeader * header,const byte * buffer){ memcpy((dbfHeader*)header,buffer,sizeof(dbfHeader)); endian_swap32((int*)&header->headerlen); } int getIDNames(dbfIDS ** list,const byte * buffer,const int start,const dbfHeader * header){ int pos = start; if(start<(header->data-1)){ *list = (dbfIDS*)malloc(sizeof(dbfIDS)); if(*list!=NULL){ memset(&(*list)->name,0x0,sizeof(dbfIDS)); memcpy(&(*list)->name,buffer+pos,sizeof((*list)->name)-1); pos += sizeof((*list)->name); memcpy(&(*list)->type,buffer+pos,sizeof((*list)->type)); pos += sizeof((*list)->type); memcpy(&(*list)->address,buffer+pos,sizeof((*list)->address)); pos += sizeof((*list)->address); memcpy(&(*list)->len,buffer+pos,sizeof((*list)->len)); return getIDNames(&(*list)->next,buffer,start+32,header)+(*list)->len; }else{ printf("Not enough memory...\n"); exit(1); } }else{ *list = NULL; //end of linked list just for heads up :D return 0; printf("Finished Reading Header information\n"); } } void getRows(dbfROWS ** rows,dbfIDS * idList,byte * buffer,const int rowlen){ dbfIDS * tmpIDS = idList;//created so we don't screw up the linked list. dbfROWS * tmpROWS = (dbfROWS*)malloc(sizeof(dbfROWS));//will transfer this to *rows after I finished iteration. *rows = tmpROWS; while(*buffer){//Run to the very END! tmpROWS->data = (byte*)malloc(tmpIDS->len+1); if(tmpROWS->data!=NULL){ memcpy(&tmpROWS->data,&buffer,tmpIDS->len); tmpROWS->data[tmpIDS->len] = 0x0;//stops it from over going its boundry. memcpy(&tmpROWS->len,&tmpIDS->len,sizeof(byte)); memcpy(&tmpROWS->type,&tmpIDS->type,sizeof(byte)); }else{ printf("Not enough memory...\n"); exit(1); } tmpROWS->next = (dbfROWS*)malloc(sizeof(dbfROWS)); if(tmpROWS->next!=NULL){ tmpROWS = tmpROWS->next; tmpROWS->next = NULL; }else{ printf("Not enough memory...\n"); exit(1); } tmpIDS = idList; buffer+=rowlen; } } int saveDBF(const char * filename,dbfFormat *updates){ return 1; }