00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "CompressMan.hpp"
00035
00036 #ifdef XDEMILL
00037 #include "UnCompCont.hpp"
00038 #endif
00039
00040 struct OrCompressorItem
00041
00042 {
00043 OrCompressorItem *next;
00044 #ifdef XMILL
00045 UserCompressor *usercompressor;
00046 #endif
00047 #ifdef XDEMILL
00048 UserUncompressor *useruncompressor;
00049 #endif
00050
00051 void *operator new(size_t size) { return mainmem.GetByteBlock(size);}
00052 void operator delete(void *ptr) {}
00053 };
00054
00055
00056
00057
00058
00059
00060
00061 class OrSepCompressorFactory;
00062
00063 struct OrSepCompressorInfo
00064 {
00065 OrCompressorItem *subcompressors;
00066
00067 void CreateSubCompressors(char *paramstr,int len)
00068
00069
00070 {
00071 OrCompressorItem **curitemref;
00072
00073 char *ptr=paramstr;
00074 char *endptr=paramstr+len;
00075
00076 subcompressors=NULL;
00077
00078 curitemref=&subcompressors;
00079
00080 while(ptr<endptr)
00081 {
00082 if((*ptr==' ')||(*ptr==',')||(*ptr=='\t')||(*ptr=='\r')||(*ptr=='\n'))
00083 {
00084 ptr++;
00085 continue;
00086 }
00087
00088 *curitemref=new OrCompressorItem();
00089
00090
00091
00092 #ifdef XMILL
00093 (*curitemref)->usercompressor=compressman.CreateCompressorInstance(ptr,endptr);
00094 #endif
00095 #ifdef XDEMILL
00096 (*curitemref)->useruncompressor=compressman.CreateUncompressorInstance(ptr,endptr);
00097 #endif
00098
00099
00100 (*curitemref)->next=NULL;
00101
00102 curitemref=&((*curitemref)->next);
00103 }
00104 }
00105 };
00106
00107
00108
00109 #ifdef XMILL
00110
00111 class OrSepCompressor : public UserCompressor
00112
00113 {
00114 friend OrSepCompressorFactory;
00115 protected:
00116
00117 OrSepCompressorInfo info;
00118
00119 long curidx;
00120 OrCompressorItem *curcompressor;
00121
00122 unsigned short curdataoffset;
00123 unsigned short curcontoffset;
00124
00125 public:
00126
00127 void ComputeProperties()
00128
00129
00130 {
00131 datasize=0;
00132 contnum=1;
00133 isrejecting=1;
00134 canoverlap=1;
00135 isfixedlen=0;
00136
00137 OrCompressorItem *item=info.subcompressors;
00138 while(item!=NULL)
00139 {
00140 if(item->usercompressor->IsRejecting()==0)
00141 isrejecting=0;
00142
00143 if(item->usercompressor->CanOverlap()==0)
00144 canoverlap=0;
00145
00146 contnum+=item->usercompressor->GetUserContNum();
00147 datasize+=item->usercompressor->GetUserDataSize();
00148 item=item->next;
00149 }
00150 }
00151
00152 void InitCompress(CompressContainer *cont,char *dataptr)
00153
00154
00155 {
00156 OrCompressorItem *item=info.subcompressors;
00157
00158 curidx=-1;
00159
00160 cont++;
00161
00162 while(item!=NULL)
00163 {
00164 item->usercompressor->InitCompress(cont,dataptr);
00165
00166 cont+=item->usercompressor->GetUserContNum();
00167 dataptr+=item->usercompressor->GetUserDataSize();
00168 item=item->next;
00169 }
00170 }
00171
00172 char ParseString(char *str,unsigned len,char *dataptr)
00173
00174
00175
00176
00177 {
00178 char *ptr1=str;
00179 OrCompressorItem *item;
00180
00181 item=info.subcompressors;
00182
00183 curidx=0;
00184 curdataoffset=0;
00185 curcontoffset=1;
00186
00187 while(item!=NULL)
00188 {
00189 if(item->usercompressor->ParseString(str,len,dataptr))
00190 break;
00191
00192 dataptr+=item->usercompressor->GetUserDataSize();
00193
00194 curidx++;
00195 curdataoffset+=item->usercompressor->GetUserDataSize();
00196 curcontoffset+=item->usercompressor->GetUserContNum();
00197
00198 item=item->next;
00199 }
00200
00201 if(item==NULL)
00202 return 0;
00203
00204 curcompressor=item;
00205
00206 return 1;
00207 }
00208
00209 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00210
00211
00212
00213
00214 {
00215 if(curidx==-1)
00216 ParseString(str,len,dataptr);
00217
00218 cont->StoreUInt32(curidx);
00219
00220 cont+=curcontoffset;
00221 dataptr+=curdataoffset;
00222
00223 curidx=-1;
00224
00225 curcompressor->usercompressor->CompressString(str,len,cont,dataptr);
00226 }
00227
00228 void FinishCompress(CompressContainer *cont,char *dataptr)
00229
00230
00231 {
00232 OrCompressorItem *item=info.subcompressors;
00233
00234 cont++;
00235
00236 while(item!=NULL)
00237 {
00238 item->usercompressor->FinishCompress(cont,dataptr);
00239
00240 cont+=item->usercompressor->GetUserContNum();
00241 dataptr+=item->usercompressor->GetUserDataSize();
00242 item=item->next;
00243 }
00244 }
00245
00246 void PrintCompressInfo(char *dataptr,unsigned long *overalluncomprsize,unsigned long *overallcomprsize)
00247
00248
00249 {
00250 OrCompressorItem *item=info.subcompressors;
00251
00252 while(item!=NULL)
00253 {
00254 item->usercompressor->PrintCompressInfo(dataptr,overalluncomprsize,overallcomprsize);
00255
00256 dataptr+=item->usercompressor->GetUserDataSize();
00257 item=item->next;
00258 }
00259 }
00260
00261 };
00262
00263 #endif // XMILL
00264
00265
00266
00267
00268
00269
00270 #ifdef XDEMILL
00271
00272 class OrSepUncompressor : public UserUncompressor
00273 {
00274 friend OrSepCompressorFactory;
00275 OrSepCompressorInfo info;
00276
00277 void ComputeProperties()
00278
00279
00280 {
00281 datasize=0;
00282 contnum=1;
00283
00284 OrCompressorItem *item=info.subcompressors;
00285 while(item!=NULL)
00286 {
00287 contnum+=item->useruncompressor->GetUserContNum();
00288 datasize+=item->useruncompressor->GetUserDataSize();
00289 item=item->next;
00290 }
00291 }
00292
00293 void InitUncompress(UncompressContainer *cont,char *dataptr)
00294
00295
00296 {
00297 OrCompressorItem *item=info.subcompressors;
00298
00299 cont++;
00300
00301 while(item!=NULL)
00302 {
00303 item->useruncompressor->InitUncompress(cont,dataptr);
00304
00305 cont+=item->useruncompressor->GetUserContNum();
00306 dataptr+=item->useruncompressor->GetUserDataSize();
00307 item=item->next;
00308 }
00309 }
00310
00311 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00312
00313
00314 {
00315
00316 unsigned long subcompressidx=cont->LoadUInt32();
00317 OrCompressorItem *item=info.subcompressors;
00318
00319 cont++;
00320
00321
00322
00323 while(subcompressidx--)
00324 {
00325 cont+=item->useruncompressor->GetUserContNum();
00326 dataptr+=item->useruncompressor->GetUserDataSize();
00327 item=item->next;
00328 }
00329
00330 item->useruncompressor->UncompressItem(cont,dataptr,output);
00331 }
00332 };
00333
00334 #endif
00335
00336
00337
00338
00339
00340 class OrSepCompressorFactory : public UserCompressorFactory
00341 {
00342 public:
00343 char *GetName() { return "or"; }
00344 char *GetDescription() { return "Variant compressor"; }
00345
00346 #ifdef XMILL
00347 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00348
00349 {
00350 if(paramstr==NULL)
00351 {
00352 Error("Division compressor 'divsep' requires a sequence of strings and compressors as parameters");
00353 Exit();
00354 }
00355
00356
00357 OrSepCompressor *orsepcompressor=new OrSepCompressor();
00358
00359 orsepcompressor->info.CreateSubCompressors(paramstr,len);
00360 orsepcompressor->ComputeProperties();
00361
00362 return orsepcompressor;
00363 }
00364 #endif
00365
00366 #ifdef XDEMILL
00367 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00368
00369 {
00370
00371
00372 OrSepUncompressor *orsepuncompressor=new OrSepUncompressor();
00373
00374 orsepuncompressor->info.CreateSubCompressors(paramstr,len);
00375 orsepuncompressor->ComputeProperties();
00376
00377 return orsepuncompressor;
00378 }
00379 #endif
00380 };
00381
00382
00383 OrSepCompressorFactory orsepcompressfactory;
00384
00385
00386
00387
00388