Recognizes if input is ogg or not.
[xiph.git] / ogg2 / src / bitwise.c
blob1dc2507361f46b68ada4618a367e14030259813f
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE Ogg Reference Library SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Ogg Reference Library SOURCE CODE IS (C) COPYRIGHT 1994-2004 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function: pack variable sized words into an octet stream
14 last mod: $Id$
16 ********************************************************************/
18 /* the 'ogg2pack_xxx functions are 'LSb' endian; if we write a word but
19 read individual bits, then we'll read the lsb first */
20 /* the 'ogg2packB_xxx functions are 'MSb' endian; if we write a word but
21 read individual bits, then we'll read the msb first */
23 #include <string.h>
24 #include <stdlib.h>
25 #include "ogginternal.h"
27 static unsigned long mask[]=
28 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
29 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
30 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
31 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
32 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
33 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
34 0x3fffffff,0x7fffffff,0xffffffff };
36 int ogg2pack_buffersize(void){
37 return sizeof(ogg2pack_buffer);
40 void ogg2pack_writeinit(ogg2pack_buffer *b,ogg2_buffer_state *bs){
41 memset(b,0,sizeof(*b));
42 b->owner=bs;
45 void ogg2packB_writeinit(ogg2pack_buffer *b,ogg2_buffer_state *bs){
46 ogg2pack_writeinit(b,bs);
47 b->owner=bs;
50 static void _ogg2pack_extend(ogg2pack_buffer *b){
51 if(b->head){
52 b->head->length=b->head->buffer->size; /* only because ->begin is always
53 zero in a write buffer */
54 b->count+=b->head->length;
55 b->head=ogg2_buffer_extend(b->head,OGG2PACK_CHUNKSIZE);
56 }else{
57 b->head=b->tail=ogg2_buffer_alloc(b->owner,OGG2PACK_CHUNKSIZE);
60 b->headptr=b->head->buffer->data;
61 b->headend=b->head->buffer->size;
64 /* Takes only up to 32 bits. */
65 void ogg2pack_write(ogg2pack_buffer *b,unsigned long value,int bits){
67 value&=mask[bits];
68 bits+=b->headbit;
70 if(!b->headend){
71 _ogg2pack_extend(b);
72 *b->headptr=value;
73 }else
74 *b->headptr|=value<<b->headbit;
76 if(bits>=8){
77 ++b->headptr;
78 if(!--b->headend)_ogg2pack_extend(b);
79 *b->headptr=value>>(8-b->headbit);
81 if(bits>=16){
82 ++b->headptr;
83 if(!--b->headend)_ogg2pack_extend(b);
84 *b->headptr=value>>(16-b->headbit);
86 if(bits>=24){
87 ++b->headptr;
88 if(!--b->headend)_ogg2pack_extend(b);
89 *b->headptr=value>>(24-b->headbit);
91 if(bits>=32){
92 ++b->headptr;
93 if(!--b->headend)_ogg2pack_extend(b);
94 if(b->headbit)
95 *b->headptr=value>>(32-b->headbit);
96 else
97 *b->headptr=0;
103 b->headbit=bits&7;
107 /* Takes only up to 32 bits. */
108 void ogg2packB_write(ogg2pack_buffer *b,unsigned long value,int bits){
110 value=(value&mask[bits])<<(32-bits);
111 bits+=b->headbit;
113 if(!b->headend){
114 _ogg2pack_extend(b);
115 *b->headptr=value>>24;
116 }else
117 *b->headptr|=value>>(24+b->headbit);
119 if(bits>=8){
120 ++b->headptr;
121 if(!--b->headend)_ogg2pack_extend(b);
122 *b->headptr=value>>(16+b->headbit);
124 if(bits>=16){
125 ++b->headptr;
126 if(!--b->headend)_ogg2pack_extend(b);
127 *b->headptr=value>>(8+b->headbit);
129 if(bits>=24){
130 ++b->headptr;
131 if(!--b->headend)_ogg2pack_extend(b);
132 *b->headptr=value>>(b->headbit);
134 if(bits>=32){
135 ++b->headptr;
136 if(!--b->headend)_ogg2pack_extend(b);
137 if(b->headbit)
138 *b->headptr=value<<(8-b->headbit);
139 else
140 *b->headptr=0;
146 b->headbit=bits&7;
149 void ogg2pack_writealign(ogg2pack_buffer *b){
150 int bits=8-b->headbit;
151 if(bits<8)
152 ogg2pack_write(b,0,bits);
155 void ogg2packB_writealign(ogg2pack_buffer *b){
156 int bits=8-b->headbit;
157 if(bits<8)
158 ogg2packB_write(b,0,bits);
161 ogg2_reference *ogg2pack_writebuffer(ogg2pack_buffer *b){
162 /* unlike generic ogg2_buffer_references, the oggpack write buffers
163 will never have any potential prefixed/unused ogg2_buffer data */
165 b->head->length=b->headptr-b->head->buffer->data+(b->headbit+7)/8;
166 return(b->tail);
169 ogg2_reference *ogg2packB_writebuffer(ogg2pack_buffer *b){
170 return ogg2pack_writebuffer(b);
173 /* frees and deallocates the ogg2pack_buffer ogg2_buffer usage */
174 void ogg2pack_writeclear(ogg2pack_buffer *b){
175 ogg2_buffer_release(b->tail);
176 memset(b,0,sizeof(*b));
179 void ogg2packB_writeclear(ogg2pack_buffer *b){
180 ogg2pack_writeclear(b);
183 /* mark read process as having run off the end */
184 static void _adv_halt(ogg2pack_buffer *b){
185 b->headptr=b->head->buffer->data+b->head->begin+b->head->length;
186 b->headend=-1;
187 b->headbit=0;
190 /* spans forward, skipping as many bytes as headend is negative; if
191 headend is zero, simply finds next byte. If we're up to the end
192 of the buffer, leaves headend at zero. If we've read past the end,
193 halt the decode process. */
194 static void _span(ogg2pack_buffer *b){
195 while(b->headend<1){
196 if(b->head->next){
197 b->count+=b->head->length;
198 b->head=b->head->next;
199 b->headptr=b->head->buffer->data+b->head->begin-b->headend;
200 b->headend+=b->head->length;
201 }else{
202 /* we've either met the end of decode, or gone past it. halt
203 only if we're past */
204 if(b->headend<0 || b->headbit)
205 /* read has fallen off the end */
206 _adv_halt(b);
208 break;
213 void ogg2pack_readinit(ogg2pack_buffer *b,ogg2_reference *r){
214 memset(b,0,sizeof(*b));
216 b->tail=b->head=r;
217 b->count=0;
218 b->headptr=b->head->buffer->data+b->head->begin;
219 b->headend=b->head->length;
220 _span(b);
223 void ogg2packB_readinit(ogg2pack_buffer *b,ogg2_reference *r){
224 ogg2pack_readinit(b,r);
227 #define _lookspan() while(!end){\
228 head=head->next;\
229 if(!head) return -1;\
230 ptr=head->buffer->data + head->begin;\
231 end=head->length;\
234 /* Read in bits without advancing the bitptr; bits <= 32 */
235 int ogg2pack_look(ogg2pack_buffer *b,int bits,unsigned long *ret){
236 unsigned long m=mask[bits];
238 bits+=b->headbit;
240 if(bits >= b->headend*8){
241 int end=b->headend;
242 unsigned char *ptr=b->headptr;
243 ogg2_reference *head=b->head;
245 if(end<0)return -1;
247 if(bits){
248 _lookspan();
249 *ret=*ptr++>>b->headbit;
250 if(bits>8){
251 --end;
252 _lookspan();
253 *ret|=*ptr++<<(8-b->headbit);
254 if(bits>16){
255 --end;
256 _lookspan();
257 *ret|=*ptr++<<(16-b->headbit);
258 if(bits>24){
259 --end;
260 _lookspan();
261 *ret|=*ptr++<<(24-b->headbit);
262 if(bits>32 && b->headbit){
263 --end;
264 _lookspan();
265 *ret|=*ptr<<(32-b->headbit);
272 }else{
274 /* make this a switch jump-table */
275 *ret=b->headptr[0]>>b->headbit;
276 if(bits>8){
277 *ret|=b->headptr[1]<<(8-b->headbit);
278 if(bits>16){
279 *ret|=b->headptr[2]<<(16-b->headbit);
280 if(bits>24){
281 *ret|=b->headptr[3]<<(24-b->headbit);
282 if(bits>32 && b->headbit)
283 *ret|=b->headptr[4]<<(32-b->headbit);
289 *ret&=m;
290 return 0;
293 /* Read in bits without advancing the bitptr; bits <= 32 */
294 int ogg2packB_look(ogg2pack_buffer *b,int bits,unsigned long *ret){
295 int m=32-bits;
297 bits+=b->headbit;
299 if(bits >= b->headend<<3){
300 int end=b->headend;
301 unsigned char *ptr=b->headptr;
302 ogg2_reference *head=b->head;
304 if(end<0)return -1;
306 if(bits){
307 _lookspan();
308 *ret=*ptr++<<(24+b->headbit);
309 if(bits>8){
310 --end;
311 _lookspan();
312 *ret|=*ptr++<<(16+b->headbit);
313 if(bits>16){
314 --end;
315 _lookspan();
316 *ret|=*ptr++<<(8+b->headbit);
317 if(bits>24){
318 --end;
319 _lookspan();
320 *ret|=*ptr++<<(b->headbit);
321 if(bits>32 && b->headbit){
322 --end;
323 _lookspan();
324 *ret|=*ptr>>(8-b->headbit);
331 }else{
333 *ret=b->headptr[0]<<(24+b->headbit);
334 if(bits>8){
335 *ret|=b->headptr[1]<<(16+b->headbit);
336 if(bits>16){
337 *ret|=b->headptr[2]<<(8+b->headbit);
338 if(bits>24){
339 *ret|=b->headptr[3]<<(b->headbit);
340 if(bits>32 && b->headbit)
341 *ret|=b->headptr[4]>>(8-b->headbit);
347 *ret>>=m;
348 return 0;
351 long ogg2pack_look1(ogg2pack_buffer *b){
352 if(b->headend<1)return -1;
353 return (b->headptr[0]>>b->headbit)&1;
356 long ogg2packB_look1(ogg2pack_buffer *b){
357 if(b->headend<1)return -1;
358 return (b->headptr[0]>>(7-b->headbit))&1;
361 /* limited to 32 at a time */
362 void ogg2pack_adv(ogg2pack_buffer *b,int bits){
363 bits+=b->headbit;
364 b->headend-=bits/8;
365 b->headbit=bits&7;
366 b->headptr+=bits/8;
367 _span(b);
370 void ogg2packB_adv(ogg2pack_buffer *b,int bits){
371 ogg2pack_adv(b,bits);
374 /* spans forward and finds next byte. Never halts */
375 static void _span_one(ogg2pack_buffer *b){
376 while(b->headend<1){
377 if(b->head->next){
378 b->count+=b->head->length;
379 b->head=b->head->next;
380 b->headptr=b->head->buffer->data+b->head->begin;
381 b->headend=b->head->length;
382 }else
383 break;
387 void ogg2pack_adv1(ogg2pack_buffer *b){
388 if(b->headend<2){
389 if(b->headend<1){
390 _adv_halt(b);
391 }else{
392 if(++b->headbit>7){
393 b->headend--;
394 b->headptr++;
395 b->headbit=0;
397 _span_one(b);
400 }else{
401 if(++b->headbit>7){
402 b->headend--;
403 b->headptr++;
404 b->headbit=0;
409 void ogg2packB_adv1(ogg2pack_buffer *b){
410 ogg2pack_adv1(b);
413 static int _halt_one(ogg2pack_buffer *b){
414 if(b->headend<1){
415 _adv_halt(b);
416 return -1;
418 return 0;
421 /* bits <= 32 */
422 int ogg2pack_read(ogg2pack_buffer *b,int bits,unsigned long *ret){
423 unsigned long m=mask[bits];
425 bits+=b->headbit;
427 if(bits >= b->headend<<3){
429 if(b->headend<0)return(-1);
431 if(bits){
432 if (_halt_one(b)) return -1;
433 *ret=*b->headptr>>b->headbit;
435 if(bits>=8){
436 ++b->headptr;
437 --b->headend;
438 _span_one(b);
439 if(bits>8){
440 if (_halt_one(b)) return -1;
441 *ret|=*b->headptr<<(8-b->headbit);
443 if(bits>=16){
444 ++b->headptr;
445 --b->headend;
446 _span_one(b);
447 if(bits>16){
448 if (_halt_one(b)) return -1;
449 *ret|=*b->headptr<<(16-b->headbit);
451 if(bits>=24){
452 ++b->headptr;
453 --b->headend;
454 _span_one(b);
455 if(bits>24){
456 if (_halt_one(b)) return -1;
457 *ret|=*b->headptr<<(24-b->headbit);
459 if(bits>=32){
460 ++b->headptr;
461 --b->headend;
462 _span_one(b);
463 if(bits>32){
464 if (_halt_one(b)) return -1;
465 if(b->headbit)*ret|=*b->headptr<<(32-b->headbit);
476 }else{
478 *ret=b->headptr[0]>>b->headbit;
479 if(bits>8){
480 *ret|=b->headptr[1]<<(8-b->headbit);
481 if(bits>16){
482 *ret|=b->headptr[2]<<(16-b->headbit);
483 if(bits>24){
484 *ret|=b->headptr[3]<<(24-b->headbit);
485 if(bits>32 && b->headbit){
486 *ret|=b->headptr[4]<<(32-b->headbit);
492 b->headptr+=bits/8;
493 b->headend-=bits/8;
496 *ret&=m;
497 b->headbit=bits&7;
498 return(0);
501 /* bits <= 32 */
502 int ogg2packB_read(ogg2pack_buffer *b,int bits,unsigned long *ret){
503 long m=32-bits;
505 bits+=b->headbit;
507 if(bits >= b->headend<<3){
509 if(b->headend<0)return(-1);
511 if(bits){
512 if (_halt_one(b)) return -1;
513 *ret=*b->headptr<<(24+b->headbit);
515 if(bits>=8){
516 ++b->headptr;
517 --b->headend;
518 _span_one(b);
519 if(bits>8){
520 if (_halt_one(b)) return -1;
521 *ret|=*b->headptr<<(16+b->headbit);
523 if(bits>=16){
524 ++b->headptr;
525 --b->headend;
526 _span_one(b);
527 if(bits>16){
528 if (_halt_one(b)) return -1;
529 *ret|=*b->headptr<<(8+b->headbit);
531 if(bits>=24){
532 ++b->headptr;
533 --b->headend;
534 _span_one(b);
535 if(bits>24){
536 if (_halt_one(b)) return -1;
537 *ret|=*b->headptr<<(b->headbit);
539 if(bits>=32){
540 ++b->headptr;
541 --b->headend;
542 _span_one(b);
543 if(bits>32){
544 if (_halt_one(b)) return -1;
545 if(b->headbit)*ret|=*b->headptr>>(8-b->headbit);
556 }else{
558 *ret=b->headptr[0]<<(24+b->headbit);
559 if(bits>8){
560 *ret|=b->headptr[1]<<(16+b->headbit);
561 if(bits>16){
562 *ret|=b->headptr[2]<<(8+b->headbit);
563 if(bits>24){
564 *ret|=b->headptr[3]<<(b->headbit);
565 if(bits>32 && b->headbit)
566 *ret|=b->headptr[4]>>(8-b->headbit);
571 b->headptr+=bits/8;
572 b->headend-=bits/8;
575 b->headbit=bits&7;
576 *ret>>=m;
577 return 0;
580 long ogg2pack_read1(ogg2pack_buffer *b){
581 long ret;
583 if(b->headend<2){
584 if (_halt_one(b)) return -1;
586 ret=b->headptr[0]>>b->headbit++;
587 b->headptr+=b->headbit/8;
588 b->headend-=b->headbit/8;
589 _span_one(b);
591 }else{
593 ret=b->headptr[0]>>b->headbit++;
594 b->headptr+=b->headbit/8;
595 b->headend-=b->headbit/8;
599 b->headbit&=7;
600 return ret&1;
603 long ogg2packB_read1(ogg2pack_buffer *b){
604 long ret;
606 if(b->headend<2){
607 if (_halt_one(b)) return -1;
609 ret=b->headptr[0]>>(7-b->headbit++);
610 b->headptr+=b->headbit/8;
611 b->headend-=b->headbit/8;
612 _span_one(b);
614 }else{
616 ret=b->headptr[0]>>(7-b->headbit++);
617 b->headptr+=b->headbit/8;
618 b->headend-=b->headbit/8;
622 b->headbit&=7;
623 return ret&1;
626 long ogg2pack_bytes(ogg2pack_buffer *b){
627 return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
628 (b->headbit+7)/8);
631 long ogg2pack_bits(ogg2pack_buffer *b){
632 return((b->count+b->headptr-b->head->buffer->data-b->head->begin)*8+
633 b->headbit);
636 long ogg2packB_bytes(ogg2pack_buffer *b){
637 return ogg2pack_bytes(b);
640 long ogg2packB_bits(ogg2pack_buffer *b){
641 return ogg2pack_bits(b);
644 int ogg2pack_eop(ogg2pack_buffer *b){
645 return(b->headend<0?-1:0);
648 int ogg2packB_eop(ogg2pack_buffer *b){
649 return ogg2pack_eop(b);
652 /* Self test of the bitwise routines; everything else is based on
653 them, so they damned well better be solid. */
655 #ifdef _V_SELFTEST
656 #include <stdio.h>
658 static int ilog(unsigned int v){
659 int ret=0;
660 while(v){
661 ret++;
662 v>>=1;
664 return(ret);
667 ogg2pack_buffer o;
668 ogg2pack_buffer r;
669 ogg2_buffer_state *bs;
670 ogg2_reference *or;
671 #define TESTWORDS 4096
673 void report(char *in){
674 fprintf(stderr,"%s",in);
675 exit(1);
678 int getbyte(ogg2_reference *or,int position){
679 while(or && position>=or->length){
680 position-=or->length;
681 or=or->next;
682 if(or==NULL){
683 fprintf(stderr,"\n\tERROR: getbyte ran off end of buffer.\n");
684 exit(1);
688 return(or->buffer->data[position+or->begin]);
691 void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
692 long bytes,i,bitcount=0;
693 ogg2_reference *or;
695 ogg2pack_writeinit(&o,bs);
696 for(i=0;i<vals;i++){
697 ogg2pack_write(&o,b[i],bits?bits:ilog(b[i]));
698 bitcount+=bits?bits:ilog(b[i]);
699 if(bitcount!=ogg2pack_bits(&o)){
700 report("wrong number of bits while writing!\n");
702 if((bitcount+7)/8!=ogg2pack_bytes(&o)){
703 report("wrong number of bytes while writing!\n");
707 or=ogg2pack_writebuffer(&o);
708 bytes=ogg2pack_bytes(&o);
710 if(bytes!=compsize)report("wrong number of bytes!\n");
711 for(i=0;i<bytes;i++)if(getbyte(or,i)!=comp[i]){
712 for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",getbyte(or,i),(int)comp[i]);
713 report("wrote incorrect value!\n");
716 bitcount=0;
717 ogg2pack_readinit(&r,or);
718 for(i=0;i<vals;i++){
719 unsigned long test;
720 int tbit=bits?bits:ilog(b[i]);
721 if(ogg2pack_look(&r,tbit,&test))
722 report("out of data!\n");
723 if(test!=(b[i]&mask[tbit])){
724 fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
725 report("looked at incorrect value!\n");
727 if(tbit==1)
728 if(ogg2pack_look1(&r)!=(int)(b[i]&mask[tbit]))
729 report("looked at single bit incorrect value!\n");
730 if(tbit==1){
731 if(ogg2pack_read1(&r)!=(int)(b[i]&mask[tbit]))
732 report("read incorrect single bit value!\n");
733 }else{
734 if(ogg2pack_read(&r,tbit,&test)){
735 report("premature end of data when reading!\n");
737 if(test!=(b[i]&mask[tbit])){
738 fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
739 report("read incorrect value!\n");
742 bitcount+=tbit;
744 if(bitcount!=ogg2pack_bits(&r))
745 report("wrong number of bits while reading!\n");
746 if((bitcount+7)/8!=ogg2pack_bytes(&r))
747 report("wrong number of bytes while reading!\n");
750 if(ogg2pack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
751 ogg2pack_writeclear(&o);
755 void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
756 long bytes,i;
757 ogg2_reference *or;
759 ogg2packB_writeinit(&o,bs);
760 for(i=0;i<vals;i++)
761 ogg2packB_write(&o,b[i],bits?bits:ilog(b[i]));
762 or=ogg2packB_writebuffer(&o);
763 bytes=ogg2packB_bytes(&o);
764 if(bytes!=compsize)report("wrong number of bytes!\n");
765 for(i=0;i<bytes;i++)if(getbyte(or,i)!=comp[i]){
766 for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",getbyte(or,i),(int)comp[i]);
767 report("wrote incorrect value!\n");
769 ogg2packB_readinit(&r,or);
770 for(i=0;i<vals;i++){
771 unsigned long test;
772 int tbit=bits?bits:ilog(b[i]);
773 if(ogg2packB_look(&r,tbit,&test))
774 report("out of data!\n");
775 if(test!=(b[i]&mask[tbit]))
776 report("looked at incorrect value!\n");
777 if(tbit==1)
778 if(ogg2packB_look1(&r)!=(int)(b[i]&mask[tbit]))
779 report("looked at single bit incorrect value!\n");
780 if(tbit==1){
781 if(ogg2packB_read1(&r)!=(int)(b[i]&mask[tbit]))
782 report("read incorrect single bit value!\n");
783 }else{
784 if(ogg2packB_read(&r,tbit,&test))
785 report("premature end of data when reading!\n");
786 if(test!=(b[i]&mask[tbit]))
787 report("read incorrect value!\n");
790 if(ogg2packB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
791 ogg2packB_writeclear(&o);
794 int flatten (unsigned char *flat){
795 unsigned char *ptr=flat;
796 ogg2_reference *head=ogg2pack_writebuffer(&o);
797 while(head){
798 memcpy(ptr,head->buffer->data+head->begin,head->length);
799 ptr+=head->length;
800 head=head->next;
802 return ptr-flat;
805 void lsbverify(unsigned long *values,int *len,unsigned char *flat) {
806 int j,k;
807 int flatbyte=0;
808 int flatbit=0;
810 /* verify written buffer is correct bit-by-bit */
811 for(j=0;j<TESTWORDS;j++){
812 for(k=0;k<len[j];k++){
813 int origbit=(values[j]>>k)&1;
814 int bit=(flat[flatbyte]>>flatbit)&1;
815 flatbit++;
816 if(flatbit>7){
817 flatbit=0;
818 ++flatbyte;
821 if(origbit!=bit){
822 fprintf(stderr,"\n\tERROR: bit mismatch! "
823 "word %d, bit %d, value %lx, len %d\n",
824 j,k,values[j],len[j]);
825 exit(1);
831 /* verify that trailing packing is zeroed */
832 while(flatbit && flatbit<8){
833 int bit=(flat[flatbyte]>>flatbit++)&1;
835 if(0!=bit){
836 fprintf(stderr,"\n\tERROR: trailing byte padding not zero!\n");
837 exit(1);
844 void msbverify(unsigned long *values,int *len,unsigned char *flat) {
845 int j,k;
846 int flatbyte=0;
847 int flatbit=0;
849 /* verify written buffer is correct bit-by-bit */
850 for(j=0;j<TESTWORDS;j++){
851 for(k=0;k<len[j];k++){
852 int origbit=(values[j]>>(len[j]-k-1))&1;
853 int bit=(flat[flatbyte]>>(7-flatbit))&1;
854 flatbit++;
855 if(flatbit>7){
856 flatbit=0;
857 ++flatbyte;
860 if(origbit!=bit){
861 fprintf(stderr,"\n\tERROR: bit mismatch! "
862 "word %d, bit %d, value %lx, len %d\n",
863 j,k,values[j],len[j]);
864 exit(1);
870 /* verify that trailing packing is zeroed */
871 while(flatbit && flatbit<8){
872 int bit=(flat[flatbyte]>>(7-flatbit++))&1;
874 if(0!=bit){
875 fprintf(stderr,"\n\tERROR: trailing byte padding not zero!\n");
876 exit(1);
882 void _end_verify(int count){
883 unsigned long temp;
884 int i;
886 /* are the proper number of bits left over? */
887 int leftover=count*8-ogg2pack_bits(&o);
888 if(leftover>7)
889 report("\nERROR: too many bits reported left over.\n");
891 /* does reading to exactly byte alignment *not* trip EOF? */
892 if(ogg2pack_read(&o,leftover,&temp))
893 report("\nERROR: read to but not past exact end tripped EOF.\n");
894 if(ogg2pack_bits(&o)!=count*8)
895 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
897 /* does EOF trip properly after a single additional bit? */
898 if(!ogg2pack_read(&o,1,&temp))
899 report("\nERROR: read past exact end did not trip EOF.\n");
900 if(ogg2pack_bits(&o)!=count*8)
901 report("\nERROR: read past exact end reported bad bitcount.\n");
903 /* does EOF stay set over additional bit reads? */
904 for(i=0;i<=32;i++){
905 if(!ogg2pack_read(&o,i,&temp))
906 report("\nERROR: EOF did not stay set on stream.\n");
907 if(ogg2pack_bits(&o)!=count*8)
908 report("\nERROR: read past exact end reported bad bitcount.\n");
912 void _end_verify2(int count){
913 int i;
915 /* are the proper number of bits left over? */
916 int leftover=count*8-ogg2pack_bits(&o);
917 if(leftover>7)
918 report("\nERROR: too many bits reported left over.\n");
920 /* does reading to exactly byte alignment *not* trip EOF? */
921 ogg2pack_adv(&o,leftover);
922 if(o.headend!=0)
923 report("\nERROR: read to but not past exact end tripped EOF.\n");
924 if(ogg2pack_bits(&o)!=count*8)
925 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
927 /* does EOF trip properly after a single additional bit? */
928 ogg2pack_adv(&o,1);
929 if(o.headend>=0)
930 report("\nERROR: read past exact end did not trip EOF.\n");
931 if(ogg2pack_bits(&o)!=count*8)
932 report("\nERROR: read past exact end reported bad bitcount.\n");
934 /* does EOF stay set over additional bit reads? */
935 for(i=0;i<=32;i++){
936 ogg2pack_adv(&o,i);
937 if(o.headend>=0)
938 report("\nERROR: EOF did not stay set on stream.\n");
939 if(ogg2pack_bits(&o)!=count*8)
940 report("\nERROR: read past exact end reported bad bitcount.\n");
944 void _end_verify3(int count){
945 unsigned long temp;
946 int i;
948 /* are the proper number of bits left over? */
949 int leftover=count*8-ogg2packB_bits(&o);
950 if(leftover>7)
951 report("\nERROR: too many bits reported left over.\n");
953 /* does reading to exactly byte alignment *not* trip EOF? */
954 if(ogg2packB_read(&o,leftover,&temp))
955 report("\nERROR: read to but not past exact end tripped EOF.\n");
956 if(ogg2packB_bits(&o)!=count*8)
957 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
959 /* does EOF trip properly after a single additional bit? */
960 if(!ogg2packB_read(&o,1,&temp))
961 report("\nERROR: read past exact end did not trip EOF.\n");
962 if(ogg2packB_bits(&o)!=count*8)
963 report("\nERROR: read past exact end reported bad bitcount.\n");
965 /* does EOF stay set over additional bit reads? */
966 for(i=0;i<=32;i++){
967 if(!ogg2packB_read(&o,i,&temp))
968 report("\nERROR: EOF did not stay set on stream.\n");
969 if(ogg2packB_bits(&o)!=count*8)
970 report("\nERROR: read past exact end reported bad bitcount.\n");
974 void _end_verify4(int count){
975 int i;
977 /* are the proper number of bits left over? */
978 int leftover=count*8-ogg2packB_bits(&o);
979 if(leftover>7)
980 report("\nERROR: too many bits reported left over.\n");
982 /* does reading to exactly byte alignment *not* trip EOF? */
983 for(i=0;i<leftover;i++){
984 ogg2packB_adv1(&o);
985 if(o.headend<0)
986 report("\nERROR: read to but not past exact end tripped EOF.\n");
988 if(ogg2packB_bits(&o)!=count*8)
989 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
991 /* does EOF trip properly after a single additional bit? */
992 ogg2packB_adv1(&o);
993 if(o.headend>=0)
994 report("\nERROR: read past exact end did not trip EOF.\n");
995 if(ogg2packB_bits(&o)!=count*8)
996 report("\nERROR: read past exact end reported bad bitcount.\n");
998 /* does EOF stay set over additional bit reads? */
999 for(i=0;i<=32;i++){
1000 ogg2packB_adv1(&o);
1001 if(o.headend>=0)
1002 report("\nERROR: EOF did not stay set on stream.\n");
1003 if(ogg2packB_bits(&o)!=count*8)
1004 report("\nERROR: read past exact end reported bad bitcount.\n");
1008 int main(void){
1009 long bytes,i;
1010 static unsigned long testbuffer1[]=
1011 {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
1012 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
1013 int test1size=43;
1015 static unsigned long testbuffer2[]=
1016 {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
1017 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
1018 85525151,0,12321,1,349528352};
1019 int test2size=21;
1021 static unsigned long testbuffer3[]=
1022 {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,
1023 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
1024 int test3size=56;
1026 static unsigned long large[]=
1027 {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
1028 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
1029 85525151,0,12321,1,2146528352};
1031 int onesize=33;
1032 static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
1033 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
1034 223,4};
1035 static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
1036 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
1037 245,251,128};
1039 int twosize=6;
1040 static int two[6]={61,255,255,251,231,29};
1041 static int twoB[6]={247,63,255,253,249,120};
1043 int threesize=54;
1044 static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
1045 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
1046 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
1047 100,52,4,14,18,86,77,1};
1048 static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
1049 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
1050 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
1051 200,20,254,4,58,106,176,144,0};
1053 int foursize=38;
1054 static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
1055 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
1056 28,2,133,0,1};
1057 static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
1058 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
1059 129,10,4,32};
1061 int fivesize=45;
1062 static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
1063 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
1064 84,75,159,2,1,0,132,192,8,0,0,18,22};
1065 static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
1066 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
1067 172,150,169,129,79,128,0,6,4,32,0,27,9,0};
1069 int sixsize=7;
1070 static int six[7]={17,177,170,242,169,19,148};
1071 static int sixB[7]={136,141,85,79,149,200,41};
1073 /* Test read/write together */
1074 /* Later we test against pregenerated bitstreams */
1075 bs=ogg2_buffer_create();
1077 fprintf(stderr,"\nSmall preclipped packing (LSb): ");
1078 cliptest(testbuffer1,test1size,0,one,onesize);
1079 fprintf(stderr,"ok.");
1081 fprintf(stderr,"\nNull bit call (LSb): ");
1082 cliptest(testbuffer3,test3size,0,two,twosize);
1083 fprintf(stderr,"ok.");
1085 fprintf(stderr,"\nLarge preclipped packing (LSb): ");
1086 cliptest(testbuffer2,test2size,0,three,threesize);
1087 fprintf(stderr,"ok.");
1089 fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
1091 ogg2pack_writeclear(&o);
1092 ogg2pack_writeinit(&o,bs);
1093 for(i=0;i<test2size;i++)
1094 ogg2pack_write(&o,large[i],32);
1095 or=ogg2pack_writebuffer(&o);
1096 bytes=ogg2pack_bytes(&o);
1097 ogg2pack_readinit(&r,or);
1098 for(i=0;i<test2size;i++){
1099 unsigned long test;
1100 if(ogg2pack_look(&r,32,&test)==-1)report("out of data. failed!");
1101 if(test!=large[i]){
1102 fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
1103 test,large[i]);
1104 report("read incorrect value!\n");
1106 ogg2pack_adv(&r,32);
1108 if(ogg2pack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
1109 fprintf(stderr,"ok.");
1111 fprintf(stderr,"\nSmall unclipped packing (LSb): ");
1112 cliptest(testbuffer1,test1size,7,four,foursize);
1113 fprintf(stderr,"ok.");
1115 fprintf(stderr,"\nLarge unclipped packing (LSb): ");
1116 cliptest(testbuffer2,test2size,17,five,fivesize);
1117 fprintf(stderr,"ok.");
1119 fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
1120 cliptest(testbuffer3,test3size,1,six,sixsize);
1121 fprintf(stderr,"ok.");
1123 fprintf(stderr,"\nTesting read past end (LSb): ");
1125 ogg2_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
1126 ogg2_reference lor={&lob,0,8,0,1};
1128 ogg2pack_readinit(&r,&lor);
1129 for(i=0;i<64;i++){
1130 if(ogg2pack_read1(&r)!=0){
1131 fprintf(stderr,"failed; got -1 prematurely.\n");
1132 exit(1);
1135 if(ogg2pack_look1(&r)!=-1 ||
1136 ogg2pack_read1(&r)!=-1){
1137 fprintf(stderr,"failed; read past end without -1.\n");
1138 exit(1);
1142 ogg2_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
1143 ogg2_reference lor={&lob,0,8,0,1};
1144 unsigned long test;
1146 ogg2pack_readinit(&r,&lor);
1147 if(ogg2pack_read(&r,30,&test)!=0 || ogg2pack_read(&r,16,&test)!=0){
1148 fprintf(stderr,"failed 2; got -1 prematurely.\n");
1149 exit(1);
1152 if(ogg2pack_look(&r,18,&test)!=0){
1153 fprintf(stderr,"failed 3; got -1 prematurely.\n");
1154 exit(1);
1156 if(ogg2pack_look(&r,19,&test)!=-1){
1157 fprintf(stderr,"failed; read past end without -1.\n");
1158 exit(1);
1160 if(ogg2pack_look(&r,32,&test)!=-1){
1161 fprintf(stderr,"failed; read past end without -1.\n");
1162 exit(1);
1165 fprintf(stderr,"ok.\n");
1166 ogg2pack_writeclear(&o);
1168 /********** lazy, cut-n-paste retest with MSb packing ***********/
1170 /* Test read/write together */
1171 /* Later we test against pregenerated bitstreams */
1173 fprintf(stderr,"\nSmall preclipped packing (MSb): ");
1174 cliptestB(testbuffer1,test1size,0,oneB,onesize);
1175 fprintf(stderr,"ok.");
1177 fprintf(stderr,"\nNull bit call (MSb): ");
1178 cliptestB(testbuffer3,test3size,0,twoB,twosize);
1179 fprintf(stderr,"ok.");
1181 fprintf(stderr,"\nLarge preclipped packing (MSb): ");
1182 cliptestB(testbuffer2,test2size,0,threeB,threesize);
1183 fprintf(stderr,"ok.");
1185 fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
1187 ogg2packB_writeinit(&o,bs);
1188 for(i=0;i<test2size;i++)
1189 ogg2packB_write(&o,large[i],32);
1190 or=ogg2packB_writebuffer(&o);
1191 bytes=ogg2packB_bytes(&o);
1192 ogg2packB_readinit(&r,or);
1193 for(i=0;i<test2size;i++){
1194 unsigned long test;
1195 if(ogg2packB_look(&r,32,&test)==-1)report("out of data. failed!");
1196 if(test!=large[i]){
1197 fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
1198 test,large[i]);
1199 report("read incorrect value!\n");
1201 ogg2packB_adv(&r,32);
1203 if(ogg2packB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
1204 fprintf(stderr,"ok.");
1206 fprintf(stderr,"\nSmall unclipped packing (MSb): ");
1207 cliptestB(testbuffer1,test1size,7,fourB,foursize);
1208 fprintf(stderr,"ok.");
1210 fprintf(stderr,"\nLarge unclipped packing (MSb): ");
1211 cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
1212 fprintf(stderr,"ok.");
1214 fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
1215 cliptestB(testbuffer3,test3size,1,sixB,sixsize);
1216 fprintf(stderr,"ok.");
1218 fprintf(stderr,"\nTesting read past end (MSb): ");
1220 ogg2_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
1221 ogg2_reference lor={&lob,0,8,0,1};
1222 unsigned long test;
1224 ogg2packB_readinit(&r,&lor);
1225 for(i=0;i<64;i++){
1226 if(ogg2packB_read(&r,1,&test)){
1227 fprintf(stderr,"failed; got -1 prematurely.\n");
1228 exit(1);
1231 if(ogg2packB_look(&r,1,&test)!=-1 ||
1232 ogg2packB_read(&r,1,&test)!=-1){
1233 fprintf(stderr,"failed; read past end without -1.\n");
1234 exit(1);
1238 ogg2_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
1239 ogg2_reference lor={&lob,0,8,0,1};
1240 unsigned long test;
1241 ogg2packB_readinit(&r,&lor);
1243 if(ogg2packB_read(&r,30,&test)!=0 || ogg2packB_read(&r,16,&test)!=0){
1244 fprintf(stderr,"failed 2; got -1 prematurely.\n");
1245 exit(1);
1248 if(ogg2packB_look(&r,18,&test)!=0){
1249 fprintf(stderr,"failed 3; got -1 prematurely.\n");
1250 exit(1);
1252 if(ogg2packB_look(&r,19,&test)!=-1){
1253 fprintf(stderr,"failed 4; read past end without -1.\n");
1254 exit(1);
1256 if(ogg2packB_look(&r,32,&test)!=-1){
1257 fprintf(stderr,"failed 5; read past end without -1.\n");
1258 exit(1);
1260 fprintf(stderr,"ok.\n\n");
1262 ogg2packB_writeclear(&o);
1264 /* now the scary shit: randomized testing */
1266 for(i=0;i<10000;i++){
1267 int j,count=0,count2=0,bitcount=0;
1268 unsigned long values[TESTWORDS];
1269 int len[TESTWORDS];
1270 unsigned char flat[4*TESTWORDS]; /* max possible needed size */
1272 fprintf(stderr,"\rRandomized testing (LSb)... (%ld) ",10000-i);
1273 ogg2pack_writeinit(&o,bs);
1275 /* generate a list of words and lengths */
1276 /* write the required number of bits out to packbuffer */
1277 for(j=0;j<TESTWORDS;j++){
1278 values[j]=rand();
1279 len[j]=(rand()%33);
1281 ogg2pack_write(&o,values[j],len[j]);
1283 bitcount+=len[j];
1284 if(ogg2pack_bits(&o)!=bitcount){
1285 fprintf(stderr,"\nERROR: Write bitcounter %d != %ld!\n",
1286 bitcount,ogg2pack_bits(&o));
1287 exit(1);
1289 if(ogg2pack_bytes(&o)!=(bitcount+7)/8){
1290 fprintf(stderr,"\nERROR: Write bytecounter %d != %ld!\n",
1291 (bitcount+7)/8,ogg2pack_bytes(&o));
1292 exit(1);
1297 /* flatten the packbuffer out to a vector */
1298 count2=flatten(flat);
1299 if(count2<(bitcount+7)/8){
1300 fprintf(stderr,"\nERROR: flattened write buffer incorrect length\n");
1301 exit(1);
1303 ogg2pack_writeclear(&o);
1305 /* verify against original list */
1306 lsbverify(values,len,flat);
1308 /* construct random-length buffer chain from flat vector; random
1309 byte starting offset within the length of the vector */
1311 ogg2_reference *or=NULL,*orl=NULL;
1312 unsigned char *ptr=flat;
1314 /* build buffer chain */
1315 while(count2){
1316 int ilen=(rand()%32);
1317 int ibegin=(rand()%32);
1319 if(ilen>count2)ilen=count2;
1321 if(or)
1322 orl=ogg2_buffer_extend(orl,ilen+ibegin);
1323 else
1324 or=orl=ogg2_buffer_alloc(bs,ilen+ibegin);
1326 memcpy(orl->buffer->data+ibegin,ptr,ilen);
1328 orl->length=ilen;
1329 orl->begin=ibegin;
1331 count2-=ilen;
1332 ptr+=ilen;
1335 if(ogg2_buffer_length(or)!=(bitcount+7)/8){
1336 fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
1337 exit(1);
1342 int begin=(rand()%TESTWORDS);
1343 int ilen=(rand()%(TESTWORDS-begin));
1344 int bitoffset,bitcount=0;
1345 unsigned long temp;
1347 for(j=0;j<begin;j++)
1348 bitcount+=len[j];
1349 or=ogg2_buffer_pretruncate(or,bitcount/8);
1350 bitoffset=bitcount%=8;
1351 for(;j<begin+ilen;j++)
1352 bitcount+=len[j];
1353 ogg2_buffer_posttruncate(or,((bitcount+7)/8));
1355 if((count=ogg2_buffer_length(or))!=(bitcount+7)/8){
1356 fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
1357 exit(1);
1360 ogg2pack_readinit(&o,or);
1362 /* verify bit count */
1363 if(ogg2pack_bits(&o)!=0){
1364 fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
1365 exit(1);
1367 if(ogg2pack_bytes(&o)!=0){
1368 fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
1369 exit(1);
1372 bitcount=bitoffset;
1373 ogg2pack_read(&o,bitoffset,&temp);
1375 /* read and compare to original list */
1376 for(j=begin;j<begin+ilen;j++){
1377 int ret;
1378 if(len[j]==1 && rand()%1)
1379 temp=ret=ogg2pack_read1(&o);
1380 else
1381 ret=ogg2pack_read(&o,len[j],&temp);
1382 if(ret<0){
1383 fprintf(stderr,"\nERROR: End of stream too soon! word: %d,%d\n",
1384 j-begin,ilen);
1385 exit(1);
1387 if(temp!=(values[j]&mask[len[j]])){
1388 fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
1389 values[j]&mask[len[j]],temp,j-begin,len[j]);
1390 exit(1);
1392 bitcount+=len[j];
1393 if(ogg2pack_bits(&o)!=bitcount){
1394 fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
1395 bitcount,ogg2pack_bits(&o));
1396 exit(1);
1398 if(ogg2pack_bytes(&o)!=(bitcount+7)/8){
1399 fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
1400 (bitcount+7)/8,ogg2pack_bytes(&o));
1401 exit(1);
1405 _end_verify(count);
1407 /* look/adv version */
1408 ogg2pack_readinit(&o,or);
1409 bitcount=bitoffset;
1410 ogg2pack_adv(&o,bitoffset);
1412 /* read and compare to original list */
1413 for(j=begin;j<begin+ilen;j++){
1414 int ret;
1415 if(len[j]==1 && rand()%1)
1416 temp=ret=ogg2pack_look1(&o);
1417 else
1418 ret=ogg2pack_look(&o,len[j],&temp);
1420 if(ret<0){
1421 fprintf(stderr,"\nERROR: End of stream too soon! word: %d\n",
1422 j-begin);
1423 exit(1);
1425 if(temp!=(values[j]&mask[len[j]])){
1426 fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %d, len %d\n",
1427 values[j]&mask[len[j]],temp,j-begin,len[j]);
1428 exit(1);
1430 if(len[j]==1 && rand()%1)
1431 ogg2pack_adv1(&o);
1432 else
1433 ogg2pack_adv(&o,len[j]);
1434 bitcount+=len[j];
1435 if(ogg2pack_bits(&o)!=bitcount){
1436 fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
1437 bitcount,ogg2pack_bits(&o));
1438 exit(1);
1440 if(ogg2pack_bytes(&o)!=(bitcount+7)/8){
1441 fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
1442 (bitcount+7)/8,ogg2pack_bytes(&o));
1443 exit(1);
1447 _end_verify2(count);
1450 ogg2_buffer_release(or);
1453 fprintf(stderr,"\rRandomized testing (LSb)... ok. \n");
1455 /* cut & paste: lazy bastahd alert */
1457 for(i=0;i<10000;i++){
1458 int j,count,count2=0,bitcount=0;
1459 unsigned long values[TESTWORDS];
1460 int len[TESTWORDS];
1461 unsigned char flat[4*TESTWORDS]; /* max possible needed size */
1463 fprintf(stderr,"\rRandomized testing (MSb)... (%ld) ",10000-i);
1464 ogg2packB_writeinit(&o,bs);
1466 /* generate a list of words and lengths */
1467 /* write the required number of bits out to packbuffer */
1468 for(j=0;j<TESTWORDS;j++){
1469 values[j]=rand();
1470 len[j]=(rand()%33);
1472 ogg2packB_write(&o,values[j],len[j]);
1474 bitcount+=len[j];
1475 if(ogg2packB_bits(&o)!=bitcount){
1476 fprintf(stderr,"\nERROR: Write bitcounter %d != %ld!\n",
1477 bitcount,ogg2packB_bits(&o));
1478 exit(1);
1480 if(ogg2packB_bytes(&o)!=(bitcount+7)/8){
1481 fprintf(stderr,"\nERROR: Write bytecounter %d != %ld!\n",
1482 (bitcount+7)/8,ogg2packB_bytes(&o));
1483 exit(1);
1488 /* flatten the packbuffer out to a vector */
1489 count2=flatten(flat);
1490 if(count2<(bitcount+7)/8){
1491 fprintf(stderr,"\nERROR: flattened write buffer incorrect length\n");
1492 exit(1);
1494 ogg2packB_writeclear(&o);
1496 /* verify against original list */
1497 msbverify(values,len,flat);
1499 /* construct random-length buffer chain from flat vector; random
1500 byte starting offset within the length of the vector */
1502 ogg2_reference *or=NULL,*orl=NULL;
1503 unsigned char *ptr=flat;
1505 /* build buffer chain */
1506 while(count2){
1507 int ilen=(rand()%32);
1508 int ibegin=(rand()%32);
1510 if(ilen>count2)ilen=count2;
1512 if(or)
1513 orl=ogg2_buffer_extend(orl,ilen+ibegin);
1514 else
1515 or=orl=ogg2_buffer_alloc(bs,ilen+ibegin);
1517 memcpy(orl->buffer->data+ibegin,ptr,ilen);
1519 orl->length=ilen;
1520 orl->begin=ibegin;
1522 count2-=ilen;
1523 ptr+=ilen;
1526 if(ogg2_buffer_length(or)!=(bitcount+7)/8){
1527 fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
1528 exit(1);
1533 int begin=(rand()%TESTWORDS);
1534 int ilen=(rand()%(TESTWORDS-begin));
1535 int bitoffset,bitcount=0;
1536 unsigned long temp;
1538 for(j=0;j<begin;j++)
1539 bitcount+=len[j];
1540 /* also exercise the split code */
1542 ogg2_reference *temp=ogg2_buffer_split(&or,0,bitcount/8);
1543 ogg2_buffer_release(temp);
1546 bitoffset=bitcount%=8;
1547 for(;j<begin+ilen;j++)
1548 bitcount+=len[j];
1549 ogg2_buffer_posttruncate(or,((bitcount+7)/8));
1551 if((count=ogg2_buffer_length(or))!=(bitcount+7)/8){
1552 fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
1553 exit(1);
1556 ogg2packB_readinit(&o,or);
1558 /* verify bit count */
1559 if(ogg2packB_bits(&o)!=0){
1560 fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
1561 exit(1);
1563 if(ogg2packB_bytes(&o)!=0){
1564 fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
1565 exit(1);
1568 bitcount=bitoffset;
1569 ogg2packB_read(&o,bitoffset,&temp);
1571 /* read and compare to original list */
1572 for(j=begin;j<begin+ilen;j++){
1573 int ret;
1574 if(len[j]==1 && rand()%1)
1575 temp=ret=ogg2packB_read1(&o);
1576 else
1577 ret=ogg2packB_read(&o,len[j],&temp);
1578 if(ret<0){
1579 fprintf(stderr,"\nERROR: End of stream too soon! word: %d,%d\n",
1580 j-begin,ilen);
1581 exit(1);
1583 if(temp!=(values[j]&mask[len[j]])){
1584 fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
1585 values[j]&mask[len[j]],temp,j-begin,len[j]);
1586 exit(1);
1588 bitcount+=len[j];
1589 if(ogg2packB_bits(&o)!=bitcount){
1590 fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
1591 bitcount,ogg2packB_bits(&o));
1592 exit(1);
1594 if(ogg2packB_bytes(&o)!=(bitcount+7)/8){
1595 fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
1596 (bitcount+7)/8,ogg2packB_bytes(&o));
1597 exit(1);
1601 _end_verify3(count);
1603 /* look/adv version */
1604 ogg2packB_readinit(&o,or);
1605 bitcount=bitoffset;
1606 ogg2packB_adv(&o,bitoffset);
1608 /* read and compare to original list */
1609 for(j=begin;j<begin+ilen;j++){
1610 int ret;
1611 if(len[j]==1 && rand()%1)
1612 temp=ret=ogg2packB_look1(&o);
1613 else
1614 ret=ogg2packB_look(&o,len[j],&temp);
1616 if(ret<0){
1617 fprintf(stderr,"\nERROR: End of stream too soon! word: %d\n",
1618 j-begin);
1619 exit(1);
1621 if(temp!=(values[j]&mask[len[j]])){
1622 fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %d, len %d\n",
1623 values[j]&mask[len[j]],temp,j-begin,len[j]);
1624 exit(1);
1626 if(len[j]==1 && rand()%1)
1627 ogg2packB_adv1(&o);
1628 else
1629 ogg2packB_adv(&o,len[j]);
1630 bitcount+=len[j];
1631 if(ogg2packB_bits(&o)!=bitcount){
1632 fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
1633 bitcount,ogg2packB_bits(&o));
1634 exit(1);
1636 if(ogg2packB_bytes(&o)!=(bitcount+7)/8){
1637 fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
1638 (bitcount+7)/8,ogg2packB_bytes(&o));
1639 exit(1);
1643 _end_verify4(count);
1646 ogg2_buffer_release(or);
1649 fprintf(stderr,"\rRandomized testing (MSb)... ok. \n");
1651 ogg2_buffer_destroy(bs);
1652 return(0);
1654 #endif /* _V_SELFTEST */