Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

SmallUncompress.hpp

Go to the documentation of this file.
00001 /*
00002 This product contains certain software code or other information
00003 ("AT&T Software") proprietary to AT&T Corp. ("AT&T").  The AT&T
00004 Software is provided to you "AS IS".  YOU ASSUME TOTAL RESPONSIBILITY
00005 AND RISK FOR USE OF THE AT&T SOFTWARE.  AT&T DOES NOT MAKE, AND
00006 EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
00007 WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00008 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
00009 TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
00010 WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
00011 PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
00012 WILL MEET YOUR REQUIREMENTS.
00013 
00014 Unless you accept a license to use the AT&T Software, you shall not
00015 reverse compile, disassemble or otherwise reverse engineer this
00016 product to ascertain the source code for any AT&T Software.
00017 
00018 (c) AT&T Corp. All rights reserved.  AT&T is a registered trademark of AT&T Corp.
00019 
00020 ***********************************************************************
00021 
00022 History:
00023 
00024       24/11/99  - initial release by Hartmut Liefke, liefke@seas.upenn.edu
00025                                      Dan Suciu,      suciu@research.att.com
00026 */
00027 
00028 //**************************************************************************
00029 //**************************************************************************
00030 
00031 // This module contains a special decompressor sequential decompression
00032 // of small blocks of data. The decompressor maintains a temporary buffer
00033 // that keeps the small blocks and that can be read sequentially by
00034 // the client.
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    // The buffer
00046    unsigned char  *buf;
00047    unsigned long  bufsize;
00048 
00049    
00050    unsigned char  *curptr;       // The current pointer into the buffer
00051    unsigned long  curdatasize;   // The remaining size
00052 
00053    Input          *input;        // The input file
00054 public:
00055 
00056    void UncompressMore(unsigned long *len)
00057       // Uncompresses at least len bytes
00058    {
00059       if(curdatasize>=*len) // Already enough data in the buffer?
00060          return;
00061 
00062       if(*len>bufsize)
00063          // Do we need more space than we have in the buffer?
00064       {
00065          // We take 'len' as the new buffer size.
00066 
00067          // But we allocate at least 30000 bytes!
00068          if(*len<30000)
00069             *len=30000;
00070 
00071          unsigned char *newbuf=(unsigned char *)malloc(*len);
00072          if(newbuf==NULL)
00073             ExitNoMem();
00074 
00075          // Copy the already existing data
00076          if(curdatasize>0)
00077             memcpy(newbuf,curptr,curdatasize);
00078 
00079          if(buf!=NULL)  // Release the old buffer
00080             free(buf);
00081 
00082          bufsize=*len;
00083          buf=newbuf;
00084          curptr=newbuf;
00085       }
00086       else
00087       {
00088          // We have enough space in the buffer
00089          // ==> Move existing data to the beginning
00090          if(curdatasize>0)
00091             memmove(buf,curptr,curdatasize);
00092 
00093          curptr=buf;
00094       }
00095 
00096       // Now we can load more data from the decompressor
00097       // and store it in the buffer
00098 
00099       // We try to read as mu
00100       unsigned long maxlen=bufsize-curdatasize;
00101 
00102       Uncompress(input,buf+curdatasize,&maxlen);
00103 
00104       curdatasize+=maxlen;
00105 
00106       // We didn't read everything that was requested?
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       // We initialize the buffer with a size of 65536L
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       // Loads 'len' bytes from the decompressor
00143       // and returns the pointer
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       // Loads a compressed integer
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       // Loads a compressed signed integer
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       // Loads a string - a string starts with a length field
00244       // and the actual data follows
00245       // The pointer to the string is stored in '*str' and
00246       // the length is returns
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

Generated on Sat Oct 13 16:08:40 2001 for XMILL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001