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 #define KATE_INTERNAL
00027 #include "kate_internal.h"
00028 
00029 #ifdef HAVE_STRING_H
00030 #include <string.h>
00031 #endif
00032 #ifdef HAVE_STDLIB_H
00033 #include <stdlib.h>
00034 #endif
00035 #include "kate_bitwise.h"
00036 
00037 #define BUFFER_INCREMENT 256
00038 
00039 static const unsigned long mask[]=
00040 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
00041  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
00042  0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
00043  0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
00044  0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
00045  0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
00046  0x3fffffff,0x7fffffff,0xffffffff };
00047 
00048 void kate_pack_writeinit(kate_pack_buffer *b){
00049   memset(b,0,sizeof(*b));
00050   b->ptr=b->buffer=kate_malloc(BUFFER_INCREMENT);
00051   b->buffer[0]='\0';
00052   b->storage=BUFFER_INCREMENT;
00053 }
00054 
00055 void kate_pack_writetrunc(kate_pack_buffer *b,long bits){
00056   long bytes=bits>>3;
00057   bits-=bytes*8;
00058   b->ptr=b->buffer+bytes;
00059   b->endbit=bits;
00060   b->endbyte=bytes;
00061   *b->ptr&=mask[bits];
00062 }
00063 
00064 
00065 void kate_pack_write(kate_pack_buffer *b,unsigned long value,int bits){
00066   if(b->endbyte+4>=b->storage){
00067     b->buffer=kate_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
00068     b->storage+=BUFFER_INCREMENT;
00069     b->ptr=b->buffer+b->endbyte;
00070   }
00071 
00072   value&=mask[bits]; 
00073   bits+=b->endbit;
00074 
00075   b->ptr[0]|=value<<b->endbit;  
00076   
00077   if(bits>=8){
00078     b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
00079     if(bits>=16){
00080       b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
00081       if(bits>=24){
00082         b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
00083         if(bits>=32){
00084           if(b->endbit)
00085             b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
00086           else
00087             b->ptr[4]=0;
00088         }
00089       }
00090     }
00091   }
00092 
00093   b->endbyte+=bits/8;
00094   b->ptr+=bits/8;
00095   b->endbit=bits&7;
00096 }
00097 
00098 void kate_pack_writealign(kate_pack_buffer *b){
00099   int bits=8-b->endbit;
00100   if(bits<8)
00101     kate_pack_write(b,0,bits);
00102 }
00103 
00104 static void kate_pack_writecopy_helper(kate_pack_buffer *b,
00105                                      void *source,
00106                                      long bits,
00107                                      void (*w)(kate_pack_buffer *,
00108                                                unsigned long,
00109                                                int),
00110                                      int msb){
00111   unsigned char *ptr=(unsigned char *)source;
00112 
00113   long bytes=bits/8;
00114   bits-=bytes*8;
00115 
00116   if(b->endbit){
00117     int i;
00118     
00119     for(i=0;i<bytes;i++)
00120       w(b,(unsigned long)(ptr[i]),8);    
00121   }else{
00122     
00123     if(b->endbyte+bytes+1>=b->storage){
00124       b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
00125       b->buffer=kate_realloc(b->buffer,b->storage);
00126       b->ptr=b->buffer+b->endbyte;
00127     }
00128 
00129     memmove(b->ptr,source,bytes);
00130     b->ptr+=bytes;
00131     b->endbyte+=bytes;
00132     *b->ptr=0;
00133 
00134   }
00135   if(bits){
00136     if(msb)
00137       w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);    
00138     else
00139       w(b,(unsigned long)(ptr[bytes]),bits);    
00140   }
00141 }
00142 
00143 void kate_pack_writecopy(kate_pack_buffer *b,void *source,long bits){
00144   kate_pack_writecopy_helper(b,source,bits,kate_pack_write,0);
00145 }
00146 
00147 void kate_pack_reset(kate_pack_buffer *b){
00148   b->ptr=b->buffer;
00149   b->buffer[0]=0;
00150   b->endbit=b->endbyte=0;
00151 }
00152 
00153 void kate_pack_writeclear(kate_pack_buffer *b){
00154   kate_free(b->buffer);
00155   memset(b,0,sizeof(*b));
00156 }
00157 
00158 void kate_pack_readinit(kate_pack_buffer *b,unsigned char *buf,int bytes){
00159   memset(b,0,sizeof(*b));
00160   b->buffer=b->ptr=buf;
00161   b->storage=bytes;
00162 }
00163 
00164 
00165 long kate_pack_look(kate_pack_buffer *b,int bits){
00166   unsigned long ret;
00167   unsigned long m=mask[bits];
00168 
00169   bits+=b->endbit;
00170 
00171   if(b->endbyte+4>=b->storage){
00172     
00173     if(b->endbyte*8+bits>b->storage*8)return(-1);
00174   }
00175   
00176   ret=b->ptr[0]>>b->endbit;
00177   if(bits>8){
00178     ret|=b->ptr[1]<<(8-b->endbit);  
00179     if(bits>16){
00180       ret|=b->ptr[2]<<(16-b->endbit);  
00181       if(bits>24){
00182         ret|=b->ptr[3]<<(24-b->endbit);  
00183         if(bits>32 && b->endbit)
00184           ret|=b->ptr[4]<<(32-b->endbit);
00185       }
00186     }
00187   }
00188   return(m&ret);
00189 }
00190 
00191 long kate_pack_look1(kate_pack_buffer *b){
00192   if(b->endbyte>=b->storage)return(-1);
00193   return((b->ptr[0]>>b->endbit)&1);
00194 }
00195 
00196 void kate_pack_adv(kate_pack_buffer *b,int bits){
00197   bits+=b->endbit;
00198   b->ptr+=bits/8;
00199   b->endbyte+=bits/8;
00200   b->endbit=bits&7;
00201 }
00202 
00203 void kate_pack_adv1(kate_pack_buffer *b){
00204   if(++(b->endbit)>7){
00205     b->endbit=0;
00206     b->ptr++;
00207     b->endbyte++;
00208   }
00209 }
00210 
00211 
00212 long kate_pack_read(kate_pack_buffer *b,int bits){
00213   long ret;
00214   unsigned long m=mask[bits];
00215 
00216   bits+=b->endbit;
00217 
00218   if(b->endbyte+4>=b->storage){
00219     
00220     ret=-1L;
00221     if(b->endbyte*8+bits>b->storage*8)goto overflow;
00222   }
00223   
00224   ret=b->ptr[0]>>b->endbit;
00225   if(bits>8){
00226     ret|=b->ptr[1]<<(8-b->endbit);  
00227     if(bits>16){
00228       ret|=b->ptr[2]<<(16-b->endbit);  
00229       if(bits>24){
00230         ret|=b->ptr[3]<<(24-b->endbit);  
00231         if(bits>32 && b->endbit){
00232           ret|=b->ptr[4]<<(32-b->endbit);
00233         }
00234       }
00235     }
00236   }
00237   ret&=m;
00238   
00239  overflow:
00240 
00241   b->ptr+=bits/8;
00242   b->endbyte+=bits/8;
00243   b->endbit=bits&7;
00244   return(ret);
00245 }
00246 
00247 long kate_pack_read1(kate_pack_buffer *b){
00248   long ret;
00249   
00250   if(b->endbyte>=b->storage){
00251     
00252     ret=-1L;
00253     goto overflow;
00254   }
00255 
00256   ret=(b->ptr[0]>>b->endbit)&1;
00257   
00258  overflow:
00259 
00260   b->endbit++;
00261   if(b->endbit>7){
00262     b->endbit=0;
00263     b->ptr++;
00264     b->endbyte++;
00265   }
00266   return(ret);
00267 }
00268 
00269 long kate_pack_bytes(kate_pack_buffer *b){
00270   return(b->endbyte+(b->endbit+7)/8);
00271 }
00272 
00273 long kate_pack_bits(kate_pack_buffer *b){
00274   return(b->endbyte*8+b->endbit);
00275 }
00276 
00277 unsigned char *kate_pack_get_buffer(kate_pack_buffer *b){
00278   return(b->buffer);
00279 }
00280 
00281 long kate_pack_readable_bits(kate_pack_buffer *b){
00282   return b->storage*8-kate_pack_bits(b);
00283 }
00284 
00285 #undef BUFFER_INCREMENT