From: <bo...@us...> - 2003-12-12 16:48:58
|
Update of /cvsroot/sharedaemon/core/src In directory sc8-pr-cvs1:/tmp/cvs-serv25603 Modified Files: ParseClass.cpp ParseClass.h osdep.h Log Message: Initial implementation of ParseClass::Write methods Index: ParseClass.cpp =================================================================== RCS file: /cvsroot/sharedaemon/core/src/ParseClass.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- ParseClass.cpp 11 Dec 2003 02:56:49 -0000 1.13 +++ ParseClass.cpp 12 Dec 2003 16:48:54 -0000 1.14 @@ -713,8 +713,272 @@ return rc; } +struct write_struct { + u8 *data; + size_t size; + struct write_struct *next; + bool free; +}; + +/* + const struct parsestruct * type; // (Sub)type of this data + unsigned char * data; // Pointer to the actual data + size_t size; // Num chars per element + size_t numPCs; // Num PCs @ the end of each element + size_t nume; // Num elements (for array) + const class ParseClass * parent; +*/ + +size_t ParseClass::IncrementalWrite( + struct write_struct * & first, + struct write_struct * & last +) const { + const struct parsestruct * ps; + struct write_struct * prev; + size_t i,done; + u8 * dataptr; + + done=0; + dataptr=data; + + first=last=new struct write_struct; + first->size=0; + first->data=NULL; + first->free=false; + + if (IsArray()) goto Array; + +// NonArray: + for (i=0;i<nume;++i) { + for (ps=type;ps;ps=ps->next) { + prev=last; + last->next=new struct write_struct; + last=last->next; + + if (ps->flags&PF_ARRAY0 + || ps->type_id==STRUCT) { + u32 num; + + Get(num,i,ps->counter_var->varname); + + if (num) { + size_t call_done; + struct write_struct *call_first; + struct write_struct *call_last; + + ParseClass * * PC; + + PC=FirstParseClassPointer(i); + PC+=ps->referer_id; + + call_done=(*PC)->IncrementalWrite( + call_first,call_last + ); + if (call_done==(size_t)-1) { + /* FIXME: Here is a Memory Leak! */ + return call_done; + } + + delete last; + prev->next=call_first; + last=call_last; + + done +=call_done; + } + } else { + switch (ps->type_id) { + case WORD: + last->data=new u8[2]; + last->free=true; + *(u16*)(last->data )=htol16(*(u16*)dataptr ); + break; + + case DWORD: + last->data=new u8[4]; + last->free=true; + *(u32*)(last->data )=htol32(*(u32*)dataptr ); + break; + + case IPPORT: + last->data=new u8[6]; + last->free=true; + *(u32*)(last->data )=htob32(*(u32*)dataptr ); + *(u16*)(last->data+4)=htol16(*(u16*)dataptr+4); + break; + + default: + last->data=dataptr; + last->free=false; + } + + dataptr +=ps->size; + done +=last->size=ps->size; + } + } + + dataptr+=numPCs*sizeof(ParseClass*); + } + + last->next=NULL; + + return done; + +Array: + size_t n=nume; + struct tag * tag; + u8 * ptr; + + if (type->type_id==BITMAP) { + fprintf( + stderr, + "%s:%s:%i: Fatal: ParseClass::IncrementalWrite is " + "not implemented for type->type_id==BITMAP.\n" + ,__FILE__,__FUNCTION__,__LINE__ + ); + exit(1); + } + if (type->type_id==TAG) { + for ( + tag=reinterpret_cast<struct tag *>(data); + n; + ++tag,--n + ) { + last->size=1+2+tag->id_len; + + prev=last; + last->next=new struct write_struct; + last=last->next; + + ptr=last->data=new u8[last->size+4]; + last->free=true; + + *ptr++=tag->type; + *(u16*)ptr=htol16(tag->id_len); + ptr+=2; + + if (!tag->id_len) { + fprintf( + stderr, + "%s:%s:%i: Fatal: ParseClass::" + "IncrementalWrite: Type id len = 0.\n" + ,__FILE__,__FUNCTION__,__LINE__ + ); + exit(1); + } + if (tag->id_len==1) { + *ptr++=tag->id.number; + } else { + memcpy(ptr,tag->id.string,tag->id_len); + ptr+=tag->id_len; + } + + switch (tag->type) { + case 2: // STRING + last->size+=2; + + *(u16*)ptr=htol16(tag->value.string.length); + + prev=last; + last->next=new struct write_struct; + last=last->next; + + last->data=tag->value.string.content; + last->size=tag->value.string.length; + last->free=false; + + break; + + case 3: + last->size+=4; + + *(u32*)ptr=htol32(tag->value.dword); + + break; + + default: + fprintf( + stderr, + "%s:%s:%i: Fatal: ParseClass::" + "IncrementalRead: Unknown tag " + "type %i\n" + ,__FILE__,__FUNCTION__,__LINE__ + ,tag->type + ); + exit(1); + } + + done+=last->size; + } + } else { + done+=last->size=size*n; + last->free=true; + + switch (type->type_id) { + case WORD: + last->data=new u8[last->size]; + + while (n--) { + *(u16*)(last->data+size*n )=htol16(*(u16*)(data+size*n )); + } + + break; + + case DWORD: + last->data=new u8[last->size]; + + while (n--) { + *(u32*)(last->data+size*n )=htol32(*(u32*)(data+size*n )); + } + + break; + + case IPPORT: + last->data=new u8[last->size]; + + while (n--) { + *(u32*)(last->data+size*n )=htob32(*(u32*)(data+size*n )); + *(u16*)(last->data+size*n+4)=htol16(*(u16*)(data+size*n+4)); + } + + break; + + default: + last->data=data; + last->free=false; + + break; + } + } + + last->next=NULL; + + return done; +} + bool ParseClass::Write(u8 * * buffer,size_t * buffsize) const { + struct write_struct *first, *last; + size_t i; + + if (((size_t)-1)==(*buffsize=IncrementalWrite(first,last))) { + return false; + } + *buffer=new u8[*buffsize]; + i=0; + while (first) { + memcpy(buffer+i,first->data,first->size); + i+=first->size; + + if (first->free) { + delete[] first->data; + } + + last=first; + first=first->next; + delete last; + } + + return true; } bool ParseClass::Write(Ed2kPacket & p,u8 protocol,u8 opcode) const { Index: ParseClass.h =================================================================== RCS file: /cvsroot/sharedaemon/core/src/ParseClass.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- ParseClass.h 9 Dec 2003 00:16:29 -0000 1.11 +++ ParseClass.h 12 Dec 2003 16:48:54 -0000 1.12 @@ -225,6 +225,11 @@ size_t IncrementalReadNonArray(const u8 * buffer,size_t buffsize); size_t IncrementalReadArray(const u8 * buffer,size_t buffsize); + size_t IncrementalWrite( + struct write_struct * & first, + struct write_struct * & last + ) const; + template <class D,class S> void GetCast(D & dst,const S & src) const { fprintf(stderr,"%s:%s:%i: FATAL: Cannot cast types.\n" ,__FILE__,__FUNCTION__,__LINE__ Index: osdep.h =================================================================== RCS file: /cvsroot/sharedaemon/core/src/osdep.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- osdep.h 11 Dec 2003 02:57:20 -0000 1.12 +++ osdep.h 12 Dec 2003 16:48:54 -0000 1.13 @@ -38,20 +38,30 @@ * l = little endian * b = big endian */ -#define ltoh32(x) ntohl(lton32(x)) -#define lton32(little_endian) ( \ - (((little_endian )&(u32)0xff)<<24) \ - |(((little_endian>> 8)&(u32)0xff)<<16) \ - |(((little_endian>>16)&(u32)0xff)<< 8) \ - |(((little_endian>>24)&(u32)0xff) ) \ + +#define bswap16(x) ( \ + ((((x) )&(u16)0xff)<< 8) \ + |((((x)>> 8)&(u16)0xff) ) \ ) -#define ltoh16(x) ntohs(lton16(x)) -#define lton16(little_endian) ( \ - (((little_endian )&(u16)0xff)<< 8) \ - |(((little_endian>> 8)&(u16)0xff) ) \ + +#define bswap32(x) ( \ + ((((x) )&(u32)0xff)<<24) \ + |((((x)>> 8)&(u32)0xff)<<16) \ + |((((x)>>16)&(u32)0xff)<< 8) \ + |((((x)>>24)&(u32)0xff) ) \ ) + +#define ltoh32(x) ntohl(lton32(x)) +#define lton32(x) bswap32(x) +#define ltoh16(x) ntohs(lton16(x)) +#define lton16(x) bswap16(x) #define btoh32(x) ntohl(x) +#define htol16(x) bswap16(htons(x)) +#define htol32(x) bswap32(htons(x)) +#define ntol16(x) bswap16(x) +#define ntol32(x) bswap32(x) +#define htob32(x) htons(x) #ifdef MACOSX #include <sys/types.h> |