00001 #define MAX_BLOCKSIZE (2L*1024L*1024L)
00002 #define MIN_DATABLOCKSIZE 512
00003
00004 struct UnpackDataBlock
00005 {
00006 unsigned long len;
00007 UnpackDataBlock *next;
00008
00009
00010 char *GetPtr() { return (char *)(this+1); }
00011 unsigned long GetLen() { return len; }
00012 };
00013
00014 struct UnpackMemBlock
00015 {
00016 unsigned long len;
00017 unsigned long used;
00018 UnpackMemBlock *next;
00019 };
00020
00021 class UnpackMemMan
00022 {
00023 UnpackMemBlock *firstblock,*lastblock;
00024 unsigned long curmaxblocksize;
00025 unsigned long neededmemoryspace;
00026
00027 UnpackMemBlock *AllocateMemBlock(UnpackMemBlock **memblockref)
00028 {
00029
00030 if(curmaxblocksize>neededmemoryspace)
00031 curmaxblocksize=neededmemoryspace;
00032
00033
00034
00035
00036 do
00037 {
00038 *memblockref=(UnpackMemBlock *)malloc(curmaxblocksize+sizeof(UnpackMemBlock));
00039 if(*memblockref!=NULL)
00040
00041 {
00042 (*memblockref)->len=curmaxblocksize;
00043 (*memblockref)->used=0;
00044 (*memblockref)->next=NULL;
00045
00046 return *memblockref;
00047 }
00048
00049 curmaxblocksize/=2;
00050
00051 if(curmaxblocksize<20000)
00052 return NULL;
00053 }
00054 while(1);
00055 }
00056
00057 public:
00058
00059 char Init(unsigned long myneededmemoryspace,unsigned long datablockcount)
00060 {
00061 neededmemoryspace=myneededmemoryspace+datablockcount*sizeof(UnpackDataBlock);
00062 curmaxblocksize=MAX_BLOCKSIZE;
00063
00064
00065 lastblock=AllocateMemBlock(&firstblock);
00066 if(lastblock==NULL)
00067 return -1;
00068
00069 return 0;
00070 }
00071
00072 UnpackDataBlock *AllocateDataBlocks(unsigned long len)
00073 {
00074 UnpackDataBlock *firstdatablock=NULL,**lastdatablockref=&firstdatablock;
00075
00076 while(lastblock->used+sizeof(UnpackDataBlock)+len>lastblock->len)
00077
00078
00079 {
00080 if(lastblock->used+sizeof(UnpackDataBlock)+MIN_DATABLOCKSIZE<lastblock->len)
00081
00082
00083 {
00084 *lastdatablockref=(UnpackDataBlock *)((char *)(lastblock+1)+lastblock->used);
00085 (*lastdatablockref)->len=lastblock->len-lastblock->used-sizeof(UnpackDataBlock);
00086 (*lastdatablockref)->next=NULL;
00087
00088 len-=(*lastdatablockref)->len;
00089 neededmemoryspace-=(*lastdatablockref)->len;
00090
00091 lastblock->used=lastblock->len;
00092
00093 lastdatablockref=&((*lastdatablockref)->next);
00094 }
00095
00096
00097
00098 lastblock=AllocateMemBlock(&(lastblock->next));
00099 if(lastblock==NULL)
00100 return NULL;
00101
00102 lastblock=lastblock->next;
00103 }
00104
00105 *lastdatablockref=(UnpackDataBlock *)((char *)(lastblock+1)+lastblock->used);
00106 (*lastdatablockref)->len=len;
00107 (*lastdatablockref)->next=NULL;
00108
00109 neededmemoryspace-=len+sizeof(UnpackDataBlock);
00110
00111 lastblock->used+=sizeof(UnpackDataBlock)+len;
00112
00113 return firstdatablock;
00114 }
00115 };
00116
00117 extern UnpackMemMan unpackmemman;