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
00035
00036 #ifndef SMALLUNCOMPRESS_HPP
00037 #define SMALLUNCOMPRESS_HPP
00038
00039 #include <string.h>
00040
00041 #include "Compress.hpp"
00042
00043 class SmallBlockUncompressor : public Uncompressor
00044 {
00045
00046 unsigned char *buf;
00047 unsigned long bufsize;
00048
00049
00050 unsigned char *curptr;
00051 unsigned long curdatasize;
00052
00053 Input *input;
00054 public:
00055
00056 void UncompressMore(unsigned long *len)
00057
00058 {
00059 if(curdatasize>=*len)
00060 return;
00061
00062 if(*len>bufsize)
00063
00064 {
00065
00066
00067
00068 if(*len<30000)
00069 *len=30000;
00070
00071 unsigned char *newbuf=(unsigned char *)malloc(*len);
00072 if(newbuf==NULL)
00073 ExitNoMem();
00074
00075
00076 if(curdatasize>0)
00077 memcpy(newbuf,curptr,curdatasize);
00078
00079 if(buf!=NULL)
00080 free(buf);
00081
00082 bufsize=*len;
00083 buf=newbuf;
00084 curptr=newbuf;
00085 }
00086 else
00087 {
00088
00089
00090 if(curdatasize>0)
00091 memmove(buf,curptr,curdatasize);
00092
00093 curptr=buf;
00094 }
00095
00096
00097
00098
00099
00100 unsigned long maxlen=bufsize-curdatasize;
00101
00102 Uncompress(input,buf+curdatasize,&maxlen);
00103
00104 curdatasize+=maxlen;
00105
00106
00107 if(curdatasize<*len)
00108 *len=curdatasize;
00109 }
00110
00111 public:
00112
00113 SmallBlockUncompressor(Input *myinput)
00114 {
00115 curdatasize=0;
00116 bufsize=0;
00117 input=myinput;
00118 curptr=buf=NULL;
00119 }
00120
00121 ~SmallBlockUncompressor()
00122 {
00123 if(buf!=NULL)
00124 free(buf);
00125 }
00126
00127 void Init()
00128 {
00129
00130 buf=(unsigned char *)malloc(65536L);
00131 if(buf==0)
00132 ExitNoMem();
00133 bufsize=65536L;
00134 curptr=buf;
00135 }
00136
00137 unsigned char *GetCurPtr() { return curptr; }
00138 unsigned long GetCurDataSize() { return curdatasize; }
00139
00140
00141 unsigned char *LoadData(unsigned long len)
00142
00143
00144 {
00145 unsigned long resultlen=len;
00146
00147 UncompressMore(&resultlen);
00148 if(resultlen!=len)
00149 {
00150 Error("Corrupt file!");
00151 Exit();
00152 }
00153 curptr+=len;
00154 curdatasize-=len;
00155
00156 return curptr-len;
00157 }
00158
00159 unsigned long LoadUInt32()
00160
00161 {
00162 unsigned long saveval;
00163
00164 if(curdatasize<4)
00165 {
00166 saveval=1;
00167 UncompressMore(&saveval);
00168 }
00169 if(*curptr<128)
00170 {
00171 curptr++;
00172 curdatasize--;
00173 return (unsigned long)curptr[-1];
00174 }
00175 else
00176 {
00177 if(*curptr<192)
00178 {
00179 saveval=2;
00180 UncompressMore(&saveval);
00181 curptr+=2;
00182 curdatasize-=2;
00183 return ((unsigned)(curptr[-2]-128)<<8)+(unsigned)curptr[-1];
00184 }
00185 else
00186 {
00187 saveval=4;
00188 UncompressMore(&saveval);
00189 curptr+=4;
00190 curdatasize-=4;
00191 return ((unsigned)(curptr[-4]-192)<<24)+
00192 ((unsigned)curptr[-3]<<16)+
00193 ((unsigned)curptr[-2]<<8)+
00194 (unsigned)curptr[-1];
00195 }
00196 }
00197 }
00198
00199 unsigned long LoadSInt32(char *isneg)
00200
00201 {
00202 unsigned long saveval;
00203 if(curdatasize<4)
00204 {
00205 saveval=1;
00206 UncompressMore(&saveval);
00207 }
00208 if(*curptr<128)
00209 {
00210 *isneg=((*curptr & 64) ? 1 : 0);
00211
00212 curptr++;
00213 curdatasize--;
00214 return (unsigned long)(curptr[-1]&63);
00215 }
00216 else
00217 {
00218 *isneg=((*curptr & 32) ? 1 : 0);
00219
00220 if(*curptr<192)
00221 {
00222 saveval=2;
00223 UncompressMore(&saveval);
00224 curptr+=2;
00225 curdatasize-=2;
00226 return ((unsigned)(curptr[-2]&31)<<8)+(unsigned)curptr[-1];
00227 }
00228 else
00229 {
00230 saveval=4;
00231 UncompressMore(&saveval);
00232 curptr+=4;
00233 curdatasize-=4;
00234 return ((unsigned)(curptr[-4]&31)<<24)+
00235 ((unsigned)curptr[-3]<<16)+
00236 ((unsigned)curptr[-2]<<8)+
00237 (unsigned)curptr[-1];
00238 }
00239 }
00240 }
00241
00242 unsigned long LoadString(char **str)
00243
00244
00245
00246
00247 {
00248 unsigned long len=LoadUInt32();
00249 unsigned long mylen=len;
00250
00251 UncompressMore(&mylen);
00252 *str=(char *)curptr;
00253 curptr+=len;
00254 curdatasize-=len;
00255 return len;
00256 }
00257 };
00258
00259 #endif