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 #include "CompressMan.hpp"
00034
00035
00036
00037
00038
00039 #ifdef XDEMILL
00040
00041 #include "UnCompCont.hpp"
00042
00043 inline char *IntToStr(long val)
00044
00045 {
00046 static char tmpstr[20];
00047
00048 char *ptr=tmpstr+19;
00049 *ptr=0;
00050
00051 if(val<0)
00052 {
00053 val=-val;
00054 do
00055 {
00056 ptr--;
00057 *ptr=(val%10)+'0';
00058 val=val/10;
00059 }
00060 while(val>0);
00061
00062 ptr--;
00063 *ptr='-';
00064 return ptr;
00065 }
00066 else
00067 {
00068 do
00069 {
00070 ptr--;
00071 *ptr=(val%10)+'0';
00072 val=val/10;
00073 }
00074 while(val>0);
00075
00076 return ptr;
00077 }
00078 }
00079
00080 inline void PrintZeros(XMLOutput *output,unsigned long zeronum)
00081
00082 {
00083 static char zerostr[]="0000000000";
00084
00085 while(zeronum>10)
00086 {
00087 output->characters(zerostr,10);
00088 zeronum-=10;
00089 }
00090 output->characters(zerostr,zeronum);
00091 }
00092
00093 inline void PrintInteger(unsigned long val,char isneg,unsigned mindigits,XMLOutput *output)
00094 {
00095 char *ptr=IntToStr(val);
00096 unsigned len=strlen(ptr);
00097
00098 if(isneg)
00099 {
00100 output->characters("-",1);
00101 if(mindigits>len+1)
00102 PrintZeros(output,mindigits-len-1);
00103 }
00104 else
00105 {
00106 if(mindigits>len)
00107 PrintZeros(output,mindigits-len);
00108 }
00109 output->characters(ptr,len);
00110 }
00111
00112 #endif
00113
00114
00115
00116
00117
00118 #ifdef XMILL
00119 class PlainTextCompressor : public UserCompressor
00120 {
00121 public:
00122 PlainTextCompressor()
00123 {
00124 datasize=0;contnum=1;isrejecting=0;canoverlap=1;isfixedlen=0;
00125 }
00126
00127 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00128 {
00129 cont->StoreUInt32(len);
00130 cont->StoreData(str,len);
00131 }
00132 };
00133 #endif
00134
00135 #ifdef XDEMILL
00136 class PlainTextUncompressor : public UserUncompressor
00137 {
00138 public:
00139 PlainTextUncompressor()
00140 {
00141 datasize=0;contnum=1;
00142 }
00143
00144 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00145 {
00146 unsigned long len=cont->LoadUInt32();
00147
00148 output->characters((char *)cont->GetDataPtr(len),len);
00149 }
00150 };
00151 #endif
00152
00153 class PlainTextCompressorFactory : public UserCompressorFactory
00154 {
00155 #ifdef XDEMILL
00156 PlainTextUncompressor uncompressor;
00157 #endif
00158 public:
00159 char *GetName() { return "t"; }
00160 char *GetDescription() { return "Plain text compressor"; }
00161
00162 #ifdef XMILL
00163 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00164 {
00165 if(paramstr!=NULL)
00166 {
00167 Error("Plain text compressor 't' should not have any arguments ('");
00168 ErrorCont(paramstr,len);
00169 Error("')");
00170 Exit();
00171 }
00172 return new PlainTextCompressor();
00173 }
00174 #endif
00175 #ifdef XDEMILL
00176 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00177 {
00178 return &uncompressor;
00179 }
00180 #endif
00181 };
00182
00183
00184
00185
00186
00187
00188 #ifdef XMILL
00189 class PrintCompressor : public UserCompressor
00190 {
00191 public:
00192 PrintCompressor()
00193 {
00194 datasize=0;contnum=0;isrejecting=1;canoverlap=1;isfixedlen=0;
00195 }
00196
00197 char ParseString(char *str,unsigned len,char *dataptr)
00198 {
00199 printf("Could not compress '");
00200 fwrite(str,len,1,stdout);
00201 printf("'...\n");
00202 return 0;
00203 }
00204
00205 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00206 {
00207 }
00208 };
00209 #endif
00210
00211 #ifdef XDEMILL
00212 class PrintUncompressor : public UserUncompressor
00213 {
00214 public:
00215 PrintUncompressor()
00216 {
00217 datasize=0;contnum=0;
00218 }
00219
00220 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00221 {
00222 }
00223 };
00224 #endif
00225
00226 class PrintCompressorFactory : public UserCompressorFactory
00227 {
00228 #ifdef XMILL
00229 PrintCompressor compressor;
00230 #endif
00231
00232 #ifdef XDEMILL
00233 PrintUncompressor uncompressor;
00234 #endif
00235 public:
00236 char *GetName() { return "p"; }
00237 char *GetDescription() { return "Print compressor"; }
00238
00239 #ifdef XMILL
00240 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00241 {
00242 return &compressor;
00243 }
00244 #endif
00245 #ifdef XDEMILL
00246 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00247 {
00248 return &uncompressor;
00249 }
00250 #endif
00251 };
00252
00253 PrintCompressorFactory printcompressor;
00254
00255
00256
00257
00258 #ifdef XMILL
00259 char ParseUnsignedInt(char *str,int len,unsigned long *val)
00260
00261
00262 {
00263 *val=0;
00264
00265 if(len==0)
00266 return 0;
00267
00268 do
00269 {
00270 if((*val)>=107374180L)
00271 return 0;
00272
00273 (*val)*=10;
00274
00275 if((*str<'0')||(*str>'9'))
00276 return 0;
00277
00278 (*val)+=(unsigned)(*str-'0');
00279 str++;
00280 len--;
00281 }
00282 while(len>0);
00283
00284 return 1;
00285 }
00286
00287 inline char ParseSignedInt(char *str,int len,unsigned long *val,unsigned char *neg)
00288
00289
00290 {
00291 if(len==0)
00292 return 0;
00293
00294 *val=0;
00295
00296 if(*str=='-')
00297 {
00298 *neg=1;
00299 str++;
00300 len--;
00301 if(len==0)
00302 return 0;
00303 }
00304 else
00305 *neg=0;
00306
00307 do
00308 {
00309 if(*val>=536870000L)
00310 return 0;
00311
00312 (*val)*=10;
00313
00314 if((*str<'0')||(*str>'9'))
00315 return 0;
00316
00317 (*val)+=(unsigned)(*str-'0');
00318 str++;
00319 len--;
00320 }
00321 while(len>0);
00322
00323 return 1;
00324 }
00325
00326 inline char ParseSignedInt(char *str,int len,long *val)
00327
00328
00329 {
00330 unsigned char isneg;
00331 if(ParseSignedInt(str,len,(unsigned long *)val,&isneg)==0)
00332 return 0;
00333
00334 if(isneg)
00335 *val=0xFFFFFFFFL-*val;
00336 return 1;
00337 }
00338 #endif
00339
00340
00341
00342
00343
00344
00345 #ifdef XMILL
00346 class UnsignedIntCompressor : public UserCompressor
00347 {
00348 unsigned long val;
00349 unsigned long mindigits;
00350 public:
00351
00352 UnsignedIntCompressor(unsigned long mymindigits)
00353 {
00354 mindigits=mymindigits;
00355 datasize=0;contnum=1;isrejecting=1;canoverlap=1;isfixedlen=0;
00356 }
00357
00358
00359
00360 char ParseString(char *str,unsigned len,char *dataptr)
00361
00362 {
00363 return ParseUnsignedInt(str,len,&val);
00364 }
00365
00366 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00367 {
00368 cont->StoreUInt32(val);
00369 }
00370 };
00371 #endif
00372
00373 #ifdef XDEMILL
00374 class UnsignedIntUncompressor : public UserUncompressor
00375 {
00376 unsigned long mindigits;
00377
00378 public:
00379
00380 UnsignedIntUncompressor(unsigned long mymindigits=0)
00381 {
00382 mindigits=mymindigits;
00383 datasize=0;contnum=1;
00384 }
00385
00386 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00387 {
00388 PrintInteger(cont->LoadUInt32(),0,mindigits,output);
00389 }
00390 };
00391 #endif
00392
00393 class UnsignedIntCompressorFactory : public UserCompressorFactory
00394 {
00395 #ifdef XDEMILL
00396 UnsignedIntUncompressor uncompressor;
00397 #endif
00398 public:
00399 char *GetName() { return "u"; }
00400 char *GetDescription() { return "Compressor for unsigned integers"; }
00401
00402 #ifdef XMILL
00403 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00404 {
00405 unsigned long mindigits=0;
00406 if(paramstr!=NULL)
00407 {
00408 char savechar=paramstr[len];
00409 paramstr[len]=0;
00410 mindigits=atoi(paramstr);
00411 paramstr[len]=savechar;
00412 if(mindigits<=0)
00413 {
00414 Error("Invalid parameter '");
00415 ErrorCont(paramstr,len);
00416 ErrorCont("' for compressor 'u8'!");
00417 Exit();
00418 }
00419 }
00420 return new UnsignedIntCompressor(mindigits);
00421 }
00422 #endif
00423
00424 #ifdef XDEMILL
00425 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00426 {
00427 unsigned long mindigits=0;
00428 if(paramstr!=NULL)
00429 {
00430 char savechar=paramstr[len];
00431 paramstr[len]=0;
00432 mindigits=atoi(paramstr);
00433 paramstr[len]=savechar;
00434 if(mindigits<=0)
00435 {
00436 Error("Invalid parameter '");
00437 ErrorCont(paramstr,len);
00438 ErrorCont("' for compressor 'u'!");
00439 Exit();
00440 }
00441 return new UnsignedIntUncompressor(mindigits);
00442 }
00443 else
00444 return &uncompressor;
00445 }
00446 #endif
00447 };
00448
00449
00450
00451
00452
00453
00454 #ifdef XMILL
00455 class UnsignedInt8Compressor : public UserCompressor
00456 {
00457 unsigned long val;
00458 unsigned long mindigits;
00459 public:
00460 UnsignedInt8Compressor(unsigned long mymindigits)
00461 {
00462 mindigits=mymindigits;
00463 datasize=0;contnum=1;isrejecting=1;canoverlap=1;isfixedlen=0;
00464 }
00465
00466
00467
00468 char ParseString(char *str,unsigned len,char *dataptr)
00469
00470 {
00471 if(ParseUnsignedInt(str,len,&val)==0)
00472 return 0;
00473
00474 return val<256;
00475 }
00476
00477 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00478 {
00479 cont->StoreChar((unsigned char)val);
00480 }
00481 };
00482 #endif
00483
00484 #ifdef XDEMILL
00485 class UnsignedInt8Uncompressor : public UserUncompressor
00486 {
00487 unsigned long mindigits;
00488 public:
00489
00490 UnsignedInt8Uncompressor(unsigned long mymindigits=0)
00491 {
00492 mindigits=mymindigits;
00493 datasize=0;contnum=1;
00494 }
00495
00496 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00497 {
00498 PrintInteger((unsigned long)(unsigned char)cont->LoadChar(),0,mindigits,output);
00499 }
00500 };
00501 #endif
00502
00503 class UnsignedInt8CompressorFactory : public UserCompressorFactory
00504 {
00505 #ifdef XDEMILL
00506 UnsignedInt8Uncompressor uncompressor;
00507 #endif
00508
00509 public:
00510 char *GetName() { return "u8"; }
00511 char *GetDescription() { return "Compressor for integers between 0 and 255"; }
00512
00513 #ifdef XMILL
00514 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00515 {
00516 unsigned long mindigits=0;
00517 if(paramstr!=NULL)
00518 {
00519 char savechar=paramstr[len];
00520 paramstr[len]=0;
00521 mindigits=atoi(paramstr);
00522 paramstr[len]=savechar;
00523 if(mindigits<=0)
00524 {
00525 Error("Invalid parameter '");
00526 ErrorCont(paramstr,len);
00527 ErrorCont("' for compressor 'u8'!");
00528 Exit();
00529 }
00530 }
00531 return new UnsignedInt8Compressor(mindigits);
00532 }
00533 #endif
00534
00535 #ifdef XDEMILL
00536 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00537 {
00538 unsigned long mindigits=0;
00539 if(paramstr!=NULL)
00540 {
00541 char savechar=paramstr[len];
00542 paramstr[len]=0;
00543 mindigits=atoi(paramstr);
00544 paramstr[len]=savechar;
00545 return new UnsignedInt8Uncompressor(mindigits);
00546 }
00547 else
00548 return &uncompressor;
00549 }
00550 #endif
00551 };
00552
00553
00554
00555
00556
00557
00558 #ifdef XMILL
00559 class SignedIntCompressor : public UserCompressor
00560 {
00561 unsigned long val;
00562 unsigned char isneg;
00563 unsigned long mindigits;
00564 public:
00565 SignedIntCompressor(unsigned long mymindigits)
00566 {
00567 mindigits=mymindigits;
00568 datasize=0;contnum=1;isrejecting=1;canoverlap=1;isfixedlen=0;
00569 }
00570
00571
00572
00573 char ParseString(char *str,unsigned len,char *dataptr)
00574 {
00575 return ParseSignedInt(str,len,&val,&isneg);
00576 }
00577
00578 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00579 {
00580 cont->StoreSInt32(isneg,val);
00581 }
00582 };
00583 #endif
00584 #ifdef XDEMILL
00585
00586 class SignedIntUncompressor : public UserUncompressor
00587 {
00588 unsigned long mindigits;
00589 public:
00590
00591 SignedIntUncompressor(unsigned long mymindigits=0)
00592 {
00593 mindigits=mymindigits;
00594 datasize=0;contnum=1;
00595 }
00596
00597 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00598 {
00599 char isneg;
00600 unsigned long val=cont->LoadSInt32(&isneg);
00601
00602 PrintInteger(val,isneg,mindigits,output);
00603 }
00604 };
00605 #endif
00606
00607 class SignedIntCompressorFactory : public UserCompressorFactory
00608 {
00609 #ifdef XDEMILL
00610 SignedIntUncompressor uncompressor;
00611 #endif
00612 public:
00613 char *GetName() { return "i"; }
00614 char *GetDescription() { return "Compressor for signed integers"; }
00615
00616 #ifdef XMILL
00617 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00618 {
00619 unsigned long mindigits=0;
00620 if(paramstr!=NULL)
00621 {
00622 char savechar=paramstr[len];
00623 paramstr[len]=0;
00624 mindigits=atoi(paramstr);
00625 paramstr[len]=savechar;
00626 if(mindigits<=0)
00627 {
00628 Error("Invalid parameter '");
00629 ErrorCont(paramstr,len);
00630 ErrorCont("' for compressor 'i'!");
00631 Exit();
00632 }
00633 }
00634 return new SignedIntCompressor(mindigits);
00635 }
00636 #endif
00637 #ifdef XDEMILL
00638 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00639 {
00640 unsigned long mindigits=0;
00641 if(paramstr!=NULL)
00642 {
00643 char savechar=paramstr[len];
00644 paramstr[len]=0;
00645 mindigits=atoi(paramstr);
00646 paramstr[len]=savechar;
00647 return new SignedIntUncompressor(mindigits);
00648 }
00649 else
00650 return &uncompressor;
00651 }
00652 #endif
00653 };
00654
00655
00656
00657
00658
00659
00660 struct DeltaCompressorState
00661
00662 {
00663 long prevvalue;
00664 };
00665
00666 #ifdef XMILL
00667 class DeltaCompressor : public UserCompressor
00668 {
00669 long val;
00670 unsigned long mindigits;
00671
00672 public:
00673
00674 DeltaCompressor(unsigned long mymindigits)
00675 {
00676 mindigits=mymindigits;
00677 datasize=sizeof(DeltaCompressorState);
00678 contnum=1;isrejecting=1;canoverlap=1;
00679 }
00680
00681 void InitCompress(CompressContainer *cont,char *dataptr)
00682 {
00683 ((DeltaCompressorState *)dataptr)->prevvalue=0;
00684 }
00685
00686 char ParseString(char *str,unsigned len,char *dataptr)
00687 {
00688 DeltaCompressorState *state=(DeltaCompressorState *)dataptr;
00689
00690 if(ParseSignedInt(str,len,&val)==0)
00691 return 0;
00692
00693
00694 return 1;
00695 }
00696
00697 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00698 {
00699 long dval;
00700 DeltaCompressorState *state=(DeltaCompressorState *)dataptr;
00701
00702 dval=val-state->prevvalue;
00703
00704 if(dval>=0)
00705 cont->StoreCompressedSInt(0,dval);
00706 else
00707 cont->StoreCompressedSInt(1,0xFFFFFFFFL-dval+1L);
00708
00709 state->prevvalue=val;
00710 }
00711 };
00712 #endif
00713
00714 #ifdef XDEMILL
00715
00716 class DeltaUncompressor : public UserUncompressor
00717 {
00718 unsigned long mindigits;
00719 public:
00720 DeltaUncompressor(unsigned long mymindigits=0)
00721 {
00722 mindigits=mymindigits;
00723
00724 datasize=sizeof(DeltaCompressorState);
00725 contnum=1;
00726 }
00727
00728 void InitUncompress(UncompressContainer *cont,char *dataptr)
00729 {
00730 ((DeltaCompressorState *)dataptr)->prevvalue=0;
00731 }
00732
00733 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00734 {
00735 DeltaCompressorState *state=(DeltaCompressorState *)dataptr;
00736
00737 state->prevvalue+=cont->LoadSInt32();
00738
00739 if(state->prevvalue&0x80000000L)
00740 PrintInteger((unsigned long)-state->prevvalue,1,mindigits,output);
00741 else
00742 PrintInteger((unsigned long) state->prevvalue,0,mindigits,output);
00743 }
00744 };
00745 #endif
00746
00747 class DeltaCompressorFactory : public UserCompressorFactory
00748 {
00749 #ifdef XDEMILL
00750 DeltaUncompressor uncompressor;
00751 #endif
00752
00753 public:
00754 char *GetName() { return "di"; }
00755 char *GetDescription() { return "Delta compressor for signed integers"; }
00756
00757 #ifdef XMILL
00758 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00759 {
00760 unsigned long mindigits=0;
00761 if(paramstr!=NULL)
00762 {
00763 char savechar=paramstr[len];
00764 paramstr[len]=0;
00765 mindigits=atoi(paramstr);
00766 paramstr[len]=savechar;
00767 if(mindigits<=0)
00768 {
00769 Error("Invalid parameter '");
00770 ErrorCont(paramstr,len);
00771 ErrorCont("' for compressor 'di'!");
00772 Exit();
00773 }
00774 }
00775 return new DeltaCompressor(mindigits);
00776 }
00777 #endif
00778 #ifdef XDEMILL
00779 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00780 {
00781 unsigned long mindigits=0;
00782 if(paramstr!=NULL)
00783 {
00784 char savechar=paramstr[len];
00785 paramstr[len]=0;
00786 mindigits=atoi(paramstr);
00787 paramstr[len]=savechar;
00788 return new DeltaUncompressor(mindigits);
00789 }
00790 else
00791 return &uncompressor;
00792 }
00793 #endif
00794 };
00795
00796
00797
00798
00799
00800
00801 #ifdef XMILL
00802 class ConstantCompressor : public UserCompressor
00803 {
00804 char *constantstr;
00805 unsigned constantstrlen;
00806
00807 public:
00808 char IsRejecting() { return 1; }
00809 char CanOverlap() { return 1; }
00810 unsigned short GetContainerNum() { return 0; }
00811
00812
00813
00814 ConstantCompressor(char *str,unsigned len)
00815 {
00816 datasize=0;contnum=0;isrejecting=1;canoverlap=1;isfixedlen=0;
00817
00818 constantstr=str;
00819 constantstrlen=len;
00820 }
00821
00822 char ParseString(char *str,unsigned len,char *dataptr)
00823 {
00824 char *ptr=constantstr;
00825
00826 while(len--)
00827 {
00828 if(*ptr!=*str)
00829 return 0;
00830 ptr++;
00831 str++;
00832 }
00833 return 1;
00834 }
00835
00836 void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
00837 {
00838 }
00839 };
00840 #endif
00841
00842 #ifdef XDEMILL
00843 class ConstantUncompressor : public UserUncompressor
00844 {
00845 char *constantstr;
00846 unsigned constantstrlen;
00847
00848 public:
00849 ConstantUncompressor(char *str,unsigned len)
00850 {
00851 datasize=0;contnum=0;
00852
00853 constantstr=str;
00854 constantstrlen=len;
00855 }
00856
00857 void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *output)
00858 {
00859 output->characters(constantstr,constantstrlen);
00860 }
00861 };
00862 #endif
00863
00864 class ConstantCompressorFactory : public UserCompressorFactory
00865 {
00866 public:
00867 char *GetName() { return "\"...\""; }
00868 char *GetDescription() { return "Constant compressor"; }
00869
00870 #ifdef XMILL
00871 UserCompressor *InstantiateCompressor(char *paramstr,int len)
00872 {
00873 if(paramstr==NULL)
00874 {
00875 Error("Constant text compressor 'c' requires string argument");
00876 Exit();
00877 }
00878 if((*paramstr!='"')||(paramstr[len-1]!='"'))
00879 {
00880 Error("Parameter '");
00881 ErrorCont(paramstr,len);
00882 ErrorCont("' is not a string");
00883 Exit();
00884 }
00885 return new ConstantCompressor(paramstr+1,len-2);
00886 }
00887 #endif
00888 #ifdef XDEMILL
00889 UserUncompressor *InstantiateUncompressor(char *paramstr,int len)
00890 {
00891 if(paramstr==NULL)
00892 {
00893 Error("Constant text compressor 'c' requires string argument");
00894 Exit();
00895 }
00896 if((*paramstr!='"')||(paramstr[len-1]!='"'))
00897 {
00898 Error("Parameter '");
00899 ErrorCont(paramstr,len);
00900 ErrorCont("' is not a string");
00901 Exit();
00902 }
00903 return new ConstantUncompressor(paramstr+1,len-2);
00904 }
00905 #endif
00906 };
00907
00908
00909
00910
00911
00912
00913 PlainTextCompressorFactory plaincompressor;
00914 UnsignedIntCompressorFactory unsignedintcompressor;
00915 UnsignedInt8CompressorFactory unsignedint8compressor;
00916 SignedIntCompressorFactory signedintcompressor;
00917 DeltaCompressorFactory deltacompressor;
00918 ConstantCompressorFactory constantcompressor;
00919 UserCompressorFactory *constantcompressfactoryptr=&constantcompressor;