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