001/* JOrbis
002 * Copyright (C) 2000 ymnk, JCraft,Inc.
003 *  
004 * Written by: 2000 ymnk<ymnk@jcaft.com>
005 *   
006 * Many thanks to 
007 *   Monty <monty@xiph.org> and 
008 *   The XIPHOPHORUS Company http://www.xiph.org/ .
009 * JOrbis has been based on their awesome works, Vorbis codec.
010 *   
011 * This program is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Library General Public License
013 * as published by the Free Software Foundation; either version 2 of
014 * the License, or (at your option) any later version.
015   
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU Library General Public License for more details.
020 * 
021 * You should have received a copy of the GNU Library General Public
022 * License along with this program; if not, write to the Free Software
023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
024 */
025
026package com.jcraft.jogg;
027
028public class Buffer{
029  private static final int BUFFER_INCREMENT=256;
030
031  private static final int[] mask={
032    0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
033    0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
034    0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
035    0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
036    0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
037    0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
038    0x3fffffff,0x7fffffff,0xffffffff
039  };
040
041  int ptr=0;
042  byte[] buffer=null;
043  int endbit=0;
044  int endbyte=0;
045  int storage=0;
046
047  public void writeinit(){
048    buffer=new byte[BUFFER_INCREMENT]; 
049    ptr=0;
050    buffer[0]=(byte)'\0';
051    storage=BUFFER_INCREMENT;
052  }
053
054  public void write(byte[] s){
055    for(int i=0; i<s.length; i++){
056      if(s[i]==0)break;
057      write(s[i],8);
058    }
059  }
060
061  public void read(byte[] s, int bytes){
062    int i=0;
063    while(bytes--!=0){
064      s[i++]=(byte)(read(8));
065    }
066  }
067
068  void reset(){
069    ptr=0;
070    buffer[0]=(byte)'\0';
071    endbit=endbyte=0;
072  }
073
074  public void writeclear(){
075    buffer=null;
076  }
077
078  public void readinit(byte[] buf, int bytes){
079    readinit(buf, 0, bytes);
080  }
081
082  public void readinit(byte[] buf, int start, int bytes){
083//System.err.println("readinit: start="+start+", bytes="+bytes);
084//for(int i=0;i<bytes; i++){
085//System.err.println(i+": "+Integer.toHexString(buf[i+start]));
086//}
087    ptr=start;
088    buffer=buf;
089    endbit=endbyte=0;
090    storage=bytes;
091  }
092
093  public void write(int value, int bits){
094//System.err.println("write: "+Integer.toHexString(value)+", bits="+bits+" ptr="+ptr+", storage="+storage+", endbyte="+endbyte);
095    if(endbyte+4>=storage){
096      byte[] foo=new byte[storage+BUFFER_INCREMENT];
097      System.arraycopy(buffer, 0, foo, 0, storage);
098      buffer=foo;
099      storage+=BUFFER_INCREMENT;
100    }
101
102    value&=mask[bits];
103    bits+=endbit;
104    buffer[ptr]|=(byte)(value<<endbit);
105
106    if(bits>=8){
107      buffer[ptr+1]=(byte)(value>>>(8-endbit));
108      if(bits>=16){
109        buffer[ptr+2]=(byte)(value>>>(16-endbit));  
110        if(bits>=24){
111          buffer[ptr+3]=(byte)(value>>>(24-endbit));  
112          if(bits>=32){
113            if(endbit>0)
114              buffer[ptr+4]=(byte)(value>>>(32-endbit));
115            else
116              buffer[ptr+4]=0;
117          }
118        }
119      }
120    }
121
122    endbyte+=bits/8;
123    ptr+=bits/8;
124    endbit=bits&7;
125  }
126
127  public int look(int bits){
128    int ret;
129    int m=mask[bits];
130
131    bits+=endbit;
132
133//System.err.println("look ptr:"+ptr+", bits="+bits+", endbit="+endbit+", storage="+storage);
134
135    if(endbyte+4>=storage){
136      if(endbyte+(bits-1)/8>=storage)return(-1);
137    }
138  
139    ret=((buffer[ptr])&0xff)>>>endbit;
140//  ret=((byte)(buffer[ptr]))>>>endbit;
141    if(bits>8){
142    ret|=((buffer[ptr+1])&0xff)<<(8-endbit);
143//      ret|=((byte)(buffer[ptr+1]))<<(8-endbit);
144      if(bits>16){
145      ret|=((buffer[ptr+2])&0xff)<<(16-endbit);
146//        ret|=((byte)(buffer[ptr+2]))<<(16-endbit);
147        if(bits>24){
148          ret|=((buffer[ptr+3])&0xff)<<(24-endbit);
149//System.err.print("ret="+Integer.toHexString(ret)+", ((byte)(buffer[ptr+3]))="+Integer.toHexString(((buffer[ptr+3])&0xff)));
150//        ret|=((byte)(buffer[ptr+3]))<<(24-endbit);
151//System.err.println(" ->ret="+Integer.toHexString(ret));
152          if(bits>32 && endbit!=0){
153            ret|=((buffer[ptr+4])&0xff)<<(32-endbit);
154//          ret|=((byte)(buffer[ptr+4]))<<(32-endbit);
155          }
156        }
157      }
158    }
159    return(m&ret);
160  }
161
162  public int look1(){
163    if(endbyte>=storage)return(-1);
164    return((buffer[ptr]>>endbit)&1);
165  }
166
167  public void adv(int bits){
168    bits+=endbit;
169    ptr+=bits/8;
170    endbyte+=bits/8;
171    endbit=bits&7;
172  }
173
174  public void adv1(){
175    ++endbit;
176    if(endbit>7){
177      endbit=0;
178      ptr++;
179      endbyte++;
180    }
181  }
182
183  public int read(int bits){
184//System.err.println(this+" read: bits="+bits+", storage="+storage+", endbyte="+endbyte);
185    int ret;
186    int m=mask[bits];
187
188    bits+=endbit;
189
190    if(endbyte+4>=storage){
191      ret=-1;
192      if(endbyte+(bits-1)/8>=storage){
193        ptr+=bits/8;
194        endbyte+=bits/8;
195        endbit=bits&7;
196        return(ret);
197      }
198    }
199
200/*  
201    ret=(byte)(buffer[ptr]>>>endbit);
202    if(bits>8){
203      ret|=(buffer[ptr+1]<<(8-endbit));  
204      if(bits>16){
205        ret|=(buffer[ptr+2]<<(16-endbit));  
206        if(bits>24){
207          ret|=(buffer[ptr+3]<<(24-endbit));  
208          if(bits>32 && endbit>0){
209            ret|=(buffer[ptr+4]<<(32-endbit));
210          }
211        }
212      }
213    }
214*/
215    ret=((buffer[ptr])&0xff)>>>endbit;
216    if(bits>8){
217    ret|=((buffer[ptr+1])&0xff)<<(8-endbit);
218//      ret|=((byte)(buffer[ptr+1]))<<(8-endbit);
219      if(bits>16){
220      ret|=((buffer[ptr+2])&0xff)<<(16-endbit);
221//        ret|=((byte)(buffer[ptr+2]))<<(16-endbit);
222        if(bits>24){
223          ret|=((buffer[ptr+3])&0xff)<<(24-endbit);
224//        ret|=((byte)(buffer[ptr+3]))<<(24-endbit);
225          if(bits>32 && endbit!=0){
226            ret|=((buffer[ptr+4])&0xff)<<(32-endbit);
227//          ret|=((byte)(buffer[ptr+4]))<<(32-endbit);
228          }
229        }
230      }
231    }
232
233    ret&=m;
234
235    ptr+=bits/8;
236//    ptr=bits/8;
237    endbyte+=bits/8;
238//    endbyte=bits/8;
239    endbit=bits&7;
240    return(ret);
241  }
242
243  public int read1(){
244    int ret;
245    if(endbyte>=storage){
246      ret=-1;
247      endbit++;
248      if(endbit>7){
249        endbit=0;
250        ptr++;
251        endbyte++;
252      }
253      return(ret);
254    }
255
256    ret=(buffer[ptr]>>endbit)&1;
257
258    endbit++;
259    if(endbit>7){
260      endbit=0;
261      ptr++;
262      endbyte++;
263    }
264    return(ret);
265  }
266
267  public int bytes(){
268    return(endbyte+(endbit+7)/8);
269  }
270
271  public int bits(){
272    return(endbyte*8+endbit);
273  }
274
275  public byte[] buffer(){
276    return(buffer);
277  }
278
279  public static int ilog(int v){
280    int ret=0;
281    while(v>0){
282      ret++;
283      v>>>=1;
284    }
285    return(ret);
286  }
287
288  public static void report(String in){
289    System.err.println(in);
290    System.exit(1);
291  }
292
293  /*
294  static void cliptest(int[] b, int vals, int bits, int[] comp, int compsize){
295    int bytes;
296    byte[] buffer;
297
298    o.reset();
299    for(int i=0;i<vals;i++){
300      o.write(b[i],((bits!=0)?bits:ilog(b[i])));
301    }
302    buffer=o.buffer();
303    bytes=o.bytes();
304System.err.println("cliptest: bytes="+bytes);
305    if(bytes!=compsize)report("wrong number of bytes!\n");
306    for(int i=0;i<bytes;i++){
307      if(buffer[i]!=(byte)comp[i]){
308        for(int j=0;j<bytes;j++){
309          System.err.println(j+": "+Integer.toHexString(buffer[j])+" "+
310                             Integer.toHexString(comp[j]));
311        }
312        report("wrote incorrect value!\n");
313      }
314    }
315System.err.println("bits: "+bits);
316    r.readinit(buffer,bytes);
317    for(int i=0;i<vals;i++){
318      int tbit=(bits!=0)?bits:ilog(b[i]);
319System.err.println(Integer.toHexString(b[i])+" tbit: "+tbit); 
320      if(r.look(tbit)==-1){
321        report("out of data!\n");
322      }
323      if(r.look(tbit)!=(b[i]&mask[tbit])){
324        report(i+" looked at incorrect value! "+Integer.toHexString(r.look(tbit))+", "+Integer.toHexString(b[i]&mask[tbit])+":"+b[i]+" bit="+tbit);
325      }
326      if(tbit==1){
327        if(r.look1()!=(b[i]&mask[tbit])){
328          report("looked at single bit incorrect value!\n");
329        }
330      }
331      if(tbit==1){
332        if(r.read1()!=(b[i]&mask[tbit])){
333          report("read incorrect single bit value!\n");
334        }
335      }
336      else{
337        if(r.read(tbit)!=(b[i]&mask[tbit])){
338          report("read incorrect value!\n");
339        }
340      }
341    }
342    if(r.bytes()!=bytes){
343      report("leftover bytes after read!\n");
344    }
345  }
346
347  static int[] testbuffer1=
348    {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
349       567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
350  static int test1size=43;
351
352  static int[] testbuffer2=
353    {216531625,1237861823,56732452,131,3212421,12325343,34547562,12313212,
354       1233432,534,5,346435231,14436467,7869299,76326614,167548585,
355       85525151,0,12321,1,349528352};
356  static int test2size=21;
357
358  static int[] large=
359    {2136531625,2137861823,56732452,131,3212421,12325343,34547562,12313212,
360       1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
361       85525151,0,12321,1,2146528352};
362
363  static int[] testbuffer3=
364    {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
365       0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
366  static int test3size=56;
367
368  static int onesize=33;
369  static int[] one={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
370                    34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
371                    223,4};
372
373  static int twosize=6;
374  static int[] two={61,255,255,251,231,29};
375
376  static int threesize=54;
377  static int[] three={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
378                      142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
379                      58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
380                      100,52,4,14,18,86,77,1};
381
382  static int foursize=38;
383  static int[] four={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
384                     132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
385                     28,2,133,0,1};
386
387  static int fivesize=45;
388  static int[] five={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
389                     241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
390                     84,75,159,2,1,0,132,192,8,0,0,18,22};
391
392  static int sixsize=7;
393  static int[] six={17,177,170,242,169,19,148};
394
395  static Buffer o=new Buffer();
396  static Buffer r=new Buffer();
397
398  public static void main(String[] arg){
399    byte[] buffer;
400    int bytes;
401//  o=new Buffer();
402//  r=new Buffer();
403
404    o.writeinit();
405
406    System.err.print("\nSmall preclipped packing: ");
407    cliptest(testbuffer1,test1size,0,one,onesize);
408    System.err.print("ok.");
409
410    System.err.print("\nNull bit call: ");
411    cliptest(testbuffer3,test3size,0,two,twosize);
412    System.err.print("ok.");
413
414    System.err.print("\nLarge preclipped packing: ");
415    cliptest(testbuffer2,test2size,0,three,threesize);
416    System.err.print("ok.");
417
418    System.err.print("\n32 bit preclipped packing: ");
419    o.reset();
420    for(int i=0;i<test2size;i++)
421      o.write(large[i],32);
422    buffer=o.buffer();
423    bytes=o.bytes();
424
425
426    r.readinit(buffer,bytes);
427    for(int i=0;i<test2size;i++){
428      if(r.look(32)==-1){
429        report("out of data. failed!");
430      }
431      if(r.look(32)!=large[i]){
432        System.err.print(r.look(32)+" != "+large[i]+" ("+
433                         Integer.toHexString(r.look(32))+"!="+
434                         Integer.toHexString(large[i])+")");
435        report("read incorrect value!\n");
436      }
437      r.adv(32);
438    }
439    if(r.bytes()!=bytes)report("leftover bytes after read!\n");
440    System.err.print("ok.");
441
442    System.err.print("\nSmall unclipped packing: ");
443    cliptest(testbuffer1,test1size,7,four,foursize);
444    System.err.print("ok.");
445
446    System.err.print("\nLarge unclipped packing: ");
447    cliptest(testbuffer2,test2size,17,five,fivesize);
448    System.err.print("ok.");
449
450    System.err.print("\nSingle bit unclicpped packing: ");
451    cliptest(testbuffer3,test3size,1,six,sixsize);
452    System.err.print("ok.");
453
454    System.err.print("\nTesting read past end: ");
455    r.readinit("\0\0\0\0\0\0\0\0".getBytes(),8);
456    for(int i=0;i<64;i++){
457      if(r.read(1)!=0){
458        System.err.print("failed; got -1 prematurely.\n");
459        System.exit(1);
460      }
461    }
462
463    if(r.look(1)!=-1 ||
464       r.read(1)!=-1){
465      System.err.print("failed; read past end without -1.\n");
466      System.exit(1);
467    }
468
469    r.readinit("\0\0\0\0\0\0\0\0".getBytes(),8);
470    if(r.read(30)!=0 || r.read(16)!=0){
471      System.err.print("failed 2; got -1 prematurely.\n");
472    System.exit(1);
473    }
474
475    if(r.look(18)!=0 ||
476       r.look(18)!=0){
477      System.err.print("failed 3; got -1 prematurely.\n");
478      System.exit(1);
479    }
480    if(r.look(19)!=-1 ||
481       r.look(19)!=-1){
482      System.err.print("failed; read past end without -1.\n");
483      System.exit(1);
484    }
485    if(r.look(32)!=-1 ||
486       r.look(32)!=-1){
487      System.err.print("failed; read past end without -1.\n");
488      System.exit(1);
489    }
490    System.err.print("ok.\n\n");
491  }
492  */
493}
494
495
496
497
498