Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /******************************************************************** |
michael@0 | 2 | * * |
michael@0 | 3 | * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * |
michael@0 | 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
michael@0 | 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
michael@0 | 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
michael@0 | 7 | * * |
michael@0 | 8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * |
michael@0 | 9 | * by the Xiph.Org Foundation http://www.xiph.org/ * |
michael@0 | 10 | * * |
michael@0 | 11 | ******************************************************************** |
michael@0 | 12 | |
michael@0 | 13 | function: packing variable sized words into an octet stream |
michael@0 | 14 | last mod: $Id: bitwise.c 18051 2011-08-04 17:56:39Z giles $ |
michael@0 | 15 | |
michael@0 | 16 | ********************************************************************/ |
michael@0 | 17 | |
michael@0 | 18 | /* We're 'LSb' endian; if we write a word but read individual bits, |
michael@0 | 19 | then we'll read the lsb first */ |
michael@0 | 20 | |
michael@0 | 21 | #include <string.h> |
michael@0 | 22 | #include <stdlib.h> |
michael@0 | 23 | #include <limits.h> |
michael@0 | 24 | #include <ogg/ogg.h> |
michael@0 | 25 | |
michael@0 | 26 | #define BUFFER_INCREMENT 256 |
michael@0 | 27 | |
michael@0 | 28 | static const unsigned long mask[]= |
michael@0 | 29 | {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, |
michael@0 | 30 | 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, |
michael@0 | 31 | 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, |
michael@0 | 32 | 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, |
michael@0 | 33 | 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, |
michael@0 | 34 | 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, |
michael@0 | 35 | 0x3fffffff,0x7fffffff,0xffffffff }; |
michael@0 | 36 | |
michael@0 | 37 | static const unsigned int mask8B[]= |
michael@0 | 38 | {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; |
michael@0 | 39 | |
michael@0 | 40 | void oggpack_writeinit(oggpack_buffer *b){ |
michael@0 | 41 | memset(b,0,sizeof(*b)); |
michael@0 | 42 | b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); |
michael@0 | 43 | b->buffer[0]='\0'; |
michael@0 | 44 | b->storage=BUFFER_INCREMENT; |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | void oggpackB_writeinit(oggpack_buffer *b){ |
michael@0 | 48 | oggpack_writeinit(b); |
michael@0 | 49 | } |
michael@0 | 50 | |
michael@0 | 51 | int oggpack_writecheck(oggpack_buffer *b){ |
michael@0 | 52 | if(!b->ptr || !b->storage)return -1; |
michael@0 | 53 | return 0; |
michael@0 | 54 | } |
michael@0 | 55 | |
michael@0 | 56 | int oggpackB_writecheck(oggpack_buffer *b){ |
michael@0 | 57 | return oggpack_writecheck(b); |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | void oggpack_writetrunc(oggpack_buffer *b,long bits){ |
michael@0 | 61 | long bytes=bits>>3; |
michael@0 | 62 | if(b->ptr){ |
michael@0 | 63 | bits-=bytes*8; |
michael@0 | 64 | b->ptr=b->buffer+bytes; |
michael@0 | 65 | b->endbit=bits; |
michael@0 | 66 | b->endbyte=bytes; |
michael@0 | 67 | *b->ptr&=mask[bits]; |
michael@0 | 68 | } |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | void oggpackB_writetrunc(oggpack_buffer *b,long bits){ |
michael@0 | 72 | long bytes=bits>>3; |
michael@0 | 73 | if(b->ptr){ |
michael@0 | 74 | bits-=bytes*8; |
michael@0 | 75 | b->ptr=b->buffer+bytes; |
michael@0 | 76 | b->endbit=bits; |
michael@0 | 77 | b->endbyte=bytes; |
michael@0 | 78 | *b->ptr&=mask8B[bits]; |
michael@0 | 79 | } |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | /* Takes only up to 32 bits. */ |
michael@0 | 83 | void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ |
michael@0 | 84 | if(bits<0 || bits>32) goto err; |
michael@0 | 85 | if(b->endbyte>=b->storage-4){ |
michael@0 | 86 | void *ret; |
michael@0 | 87 | if(!b->ptr)return; |
michael@0 | 88 | if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; |
michael@0 | 89 | ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); |
michael@0 | 90 | if(!ret) goto err; |
michael@0 | 91 | b->buffer=ret; |
michael@0 | 92 | b->storage+=BUFFER_INCREMENT; |
michael@0 | 93 | b->ptr=b->buffer+b->endbyte; |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | value&=mask[bits]; |
michael@0 | 97 | bits+=b->endbit; |
michael@0 | 98 | |
michael@0 | 99 | b->ptr[0]|=value<<b->endbit; |
michael@0 | 100 | |
michael@0 | 101 | if(bits>=8){ |
michael@0 | 102 | b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); |
michael@0 | 103 | if(bits>=16){ |
michael@0 | 104 | b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); |
michael@0 | 105 | if(bits>=24){ |
michael@0 | 106 | b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); |
michael@0 | 107 | if(bits>=32){ |
michael@0 | 108 | if(b->endbit) |
michael@0 | 109 | b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); |
michael@0 | 110 | else |
michael@0 | 111 | b->ptr[4]=0; |
michael@0 | 112 | } |
michael@0 | 113 | } |
michael@0 | 114 | } |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | b->endbyte+=bits/8; |
michael@0 | 118 | b->ptr+=bits/8; |
michael@0 | 119 | b->endbit=bits&7; |
michael@0 | 120 | return; |
michael@0 | 121 | err: |
michael@0 | 122 | oggpack_writeclear(b); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | /* Takes only up to 32 bits. */ |
michael@0 | 126 | void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ |
michael@0 | 127 | if(bits<0 || bits>32) goto err; |
michael@0 | 128 | if(b->endbyte>=b->storage-4){ |
michael@0 | 129 | void *ret; |
michael@0 | 130 | if(!b->ptr)return; |
michael@0 | 131 | if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; |
michael@0 | 132 | ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); |
michael@0 | 133 | if(!ret) goto err; |
michael@0 | 134 | b->buffer=ret; |
michael@0 | 135 | b->storage+=BUFFER_INCREMENT; |
michael@0 | 136 | b->ptr=b->buffer+b->endbyte; |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | value=(value&mask[bits])<<(32-bits); |
michael@0 | 140 | bits+=b->endbit; |
michael@0 | 141 | |
michael@0 | 142 | b->ptr[0]|=value>>(24+b->endbit); |
michael@0 | 143 | |
michael@0 | 144 | if(bits>=8){ |
michael@0 | 145 | b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); |
michael@0 | 146 | if(bits>=16){ |
michael@0 | 147 | b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); |
michael@0 | 148 | if(bits>=24){ |
michael@0 | 149 | b->ptr[3]=(unsigned char)(value>>(b->endbit)); |
michael@0 | 150 | if(bits>=32){ |
michael@0 | 151 | if(b->endbit) |
michael@0 | 152 | b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); |
michael@0 | 153 | else |
michael@0 | 154 | b->ptr[4]=0; |
michael@0 | 155 | } |
michael@0 | 156 | } |
michael@0 | 157 | } |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | b->endbyte+=bits/8; |
michael@0 | 161 | b->ptr+=bits/8; |
michael@0 | 162 | b->endbit=bits&7; |
michael@0 | 163 | return; |
michael@0 | 164 | err: |
michael@0 | 165 | oggpack_writeclear(b); |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | void oggpack_writealign(oggpack_buffer *b){ |
michael@0 | 169 | int bits=8-b->endbit; |
michael@0 | 170 | if(bits<8) |
michael@0 | 171 | oggpack_write(b,0,bits); |
michael@0 | 172 | } |
michael@0 | 173 | |
michael@0 | 174 | void oggpackB_writealign(oggpack_buffer *b){ |
michael@0 | 175 | int bits=8-b->endbit; |
michael@0 | 176 | if(bits<8) |
michael@0 | 177 | oggpackB_write(b,0,bits); |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | static void oggpack_writecopy_helper(oggpack_buffer *b, |
michael@0 | 181 | void *source, |
michael@0 | 182 | long bits, |
michael@0 | 183 | void (*w)(oggpack_buffer *, |
michael@0 | 184 | unsigned long, |
michael@0 | 185 | int), |
michael@0 | 186 | int msb){ |
michael@0 | 187 | unsigned char *ptr=(unsigned char *)source; |
michael@0 | 188 | |
michael@0 | 189 | long bytes=bits/8; |
michael@0 | 190 | bits-=bytes*8; |
michael@0 | 191 | |
michael@0 | 192 | if(b->endbit){ |
michael@0 | 193 | int i; |
michael@0 | 194 | /* unaligned copy. Do it the hard way. */ |
michael@0 | 195 | for(i=0;i<bytes;i++) |
michael@0 | 196 | w(b,(unsigned long)(ptr[i]),8); |
michael@0 | 197 | }else{ |
michael@0 | 198 | /* aligned block copy */ |
michael@0 | 199 | if(b->endbyte+bytes+1>=b->storage){ |
michael@0 | 200 | void *ret; |
michael@0 | 201 | if(!b->ptr) goto err; |
michael@0 | 202 | if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err; |
michael@0 | 203 | b->storage=b->endbyte+bytes+BUFFER_INCREMENT; |
michael@0 | 204 | ret=_ogg_realloc(b->buffer,b->storage); |
michael@0 | 205 | if(!ret) goto err; |
michael@0 | 206 | b->buffer=ret; |
michael@0 | 207 | b->ptr=b->buffer+b->endbyte; |
michael@0 | 208 | } |
michael@0 | 209 | |
michael@0 | 210 | memmove(b->ptr,source,bytes); |
michael@0 | 211 | b->ptr+=bytes; |
michael@0 | 212 | b->endbyte+=bytes; |
michael@0 | 213 | *b->ptr=0; |
michael@0 | 214 | |
michael@0 | 215 | } |
michael@0 | 216 | if(bits){ |
michael@0 | 217 | if(msb) |
michael@0 | 218 | w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); |
michael@0 | 219 | else |
michael@0 | 220 | w(b,(unsigned long)(ptr[bytes]),bits); |
michael@0 | 221 | } |
michael@0 | 222 | return; |
michael@0 | 223 | err: |
michael@0 | 224 | oggpack_writeclear(b); |
michael@0 | 225 | } |
michael@0 | 226 | |
michael@0 | 227 | void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ |
michael@0 | 228 | oggpack_writecopy_helper(b,source,bits,oggpack_write,0); |
michael@0 | 229 | } |
michael@0 | 230 | |
michael@0 | 231 | void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ |
michael@0 | 232 | oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); |
michael@0 | 233 | } |
michael@0 | 234 | |
michael@0 | 235 | void oggpack_reset(oggpack_buffer *b){ |
michael@0 | 236 | if(!b->ptr)return; |
michael@0 | 237 | b->ptr=b->buffer; |
michael@0 | 238 | b->buffer[0]=0; |
michael@0 | 239 | b->endbit=b->endbyte=0; |
michael@0 | 240 | } |
michael@0 | 241 | |
michael@0 | 242 | void oggpackB_reset(oggpack_buffer *b){ |
michael@0 | 243 | oggpack_reset(b); |
michael@0 | 244 | } |
michael@0 | 245 | |
michael@0 | 246 | void oggpack_writeclear(oggpack_buffer *b){ |
michael@0 | 247 | if(b->buffer)_ogg_free(b->buffer); |
michael@0 | 248 | memset(b,0,sizeof(*b)); |
michael@0 | 249 | } |
michael@0 | 250 | |
michael@0 | 251 | void oggpackB_writeclear(oggpack_buffer *b){ |
michael@0 | 252 | oggpack_writeclear(b); |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ |
michael@0 | 256 | memset(b,0,sizeof(*b)); |
michael@0 | 257 | b->buffer=b->ptr=buf; |
michael@0 | 258 | b->storage=bytes; |
michael@0 | 259 | } |
michael@0 | 260 | |
michael@0 | 261 | void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ |
michael@0 | 262 | oggpack_readinit(b,buf,bytes); |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | /* Read in bits without advancing the bitptr; bits <= 32 */ |
michael@0 | 266 | long oggpack_look(oggpack_buffer *b,int bits){ |
michael@0 | 267 | unsigned long ret; |
michael@0 | 268 | unsigned long m; |
michael@0 | 269 | |
michael@0 | 270 | if(bits<0 || bits>32) return -1; |
michael@0 | 271 | m=mask[bits]; |
michael@0 | 272 | bits+=b->endbit; |
michael@0 | 273 | |
michael@0 | 274 | if(b->endbyte >= b->storage-4){ |
michael@0 | 275 | /* not the main path */ |
michael@0 | 276 | if(b->endbyte > b->storage-((bits+7)>>3)) return -1; |
michael@0 | 277 | /* special case to avoid reading b->ptr[0], which might be past the end of |
michael@0 | 278 | the buffer; also skips some useless accounting */ |
michael@0 | 279 | else if(!bits)return(0L); |
michael@0 | 280 | } |
michael@0 | 281 | |
michael@0 | 282 | ret=b->ptr[0]>>b->endbit; |
michael@0 | 283 | if(bits>8){ |
michael@0 | 284 | ret|=b->ptr[1]<<(8-b->endbit); |
michael@0 | 285 | if(bits>16){ |
michael@0 | 286 | ret|=b->ptr[2]<<(16-b->endbit); |
michael@0 | 287 | if(bits>24){ |
michael@0 | 288 | ret|=b->ptr[3]<<(24-b->endbit); |
michael@0 | 289 | if(bits>32 && b->endbit) |
michael@0 | 290 | ret|=b->ptr[4]<<(32-b->endbit); |
michael@0 | 291 | } |
michael@0 | 292 | } |
michael@0 | 293 | } |
michael@0 | 294 | return(m&ret); |
michael@0 | 295 | } |
michael@0 | 296 | |
michael@0 | 297 | /* Read in bits without advancing the bitptr; bits <= 32 */ |
michael@0 | 298 | long oggpackB_look(oggpack_buffer *b,int bits){ |
michael@0 | 299 | unsigned long ret; |
michael@0 | 300 | int m=32-bits; |
michael@0 | 301 | |
michael@0 | 302 | if(m<0 || m>32) return -1; |
michael@0 | 303 | bits+=b->endbit; |
michael@0 | 304 | |
michael@0 | 305 | if(b->endbyte >= b->storage-4){ |
michael@0 | 306 | /* not the main path */ |
michael@0 | 307 | if(b->endbyte > b->storage-((bits+7)>>3)) return -1; |
michael@0 | 308 | /* special case to avoid reading b->ptr[0], which might be past the end of |
michael@0 | 309 | the buffer; also skips some useless accounting */ |
michael@0 | 310 | else if(!bits)return(0L); |
michael@0 | 311 | } |
michael@0 | 312 | |
michael@0 | 313 | ret=b->ptr[0]<<(24+b->endbit); |
michael@0 | 314 | if(bits>8){ |
michael@0 | 315 | ret|=b->ptr[1]<<(16+b->endbit); |
michael@0 | 316 | if(bits>16){ |
michael@0 | 317 | ret|=b->ptr[2]<<(8+b->endbit); |
michael@0 | 318 | if(bits>24){ |
michael@0 | 319 | ret|=b->ptr[3]<<(b->endbit); |
michael@0 | 320 | if(bits>32 && b->endbit) |
michael@0 | 321 | ret|=b->ptr[4]>>(8-b->endbit); |
michael@0 | 322 | } |
michael@0 | 323 | } |
michael@0 | 324 | } |
michael@0 | 325 | return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); |
michael@0 | 326 | } |
michael@0 | 327 | |
michael@0 | 328 | long oggpack_look1(oggpack_buffer *b){ |
michael@0 | 329 | if(b->endbyte>=b->storage)return(-1); |
michael@0 | 330 | return((b->ptr[0]>>b->endbit)&1); |
michael@0 | 331 | } |
michael@0 | 332 | |
michael@0 | 333 | long oggpackB_look1(oggpack_buffer *b){ |
michael@0 | 334 | if(b->endbyte>=b->storage)return(-1); |
michael@0 | 335 | return((b->ptr[0]>>(7-b->endbit))&1); |
michael@0 | 336 | } |
michael@0 | 337 | |
michael@0 | 338 | void oggpack_adv(oggpack_buffer *b,int bits){ |
michael@0 | 339 | bits+=b->endbit; |
michael@0 | 340 | |
michael@0 | 341 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; |
michael@0 | 342 | |
michael@0 | 343 | b->ptr+=bits/8; |
michael@0 | 344 | b->endbyte+=bits/8; |
michael@0 | 345 | b->endbit=bits&7; |
michael@0 | 346 | return; |
michael@0 | 347 | |
michael@0 | 348 | overflow: |
michael@0 | 349 | b->ptr=NULL; |
michael@0 | 350 | b->endbyte=b->storage; |
michael@0 | 351 | b->endbit=1; |
michael@0 | 352 | } |
michael@0 | 353 | |
michael@0 | 354 | void oggpackB_adv(oggpack_buffer *b,int bits){ |
michael@0 | 355 | oggpack_adv(b,bits); |
michael@0 | 356 | } |
michael@0 | 357 | |
michael@0 | 358 | void oggpack_adv1(oggpack_buffer *b){ |
michael@0 | 359 | if(++(b->endbit)>7){ |
michael@0 | 360 | b->endbit=0; |
michael@0 | 361 | b->ptr++; |
michael@0 | 362 | b->endbyte++; |
michael@0 | 363 | } |
michael@0 | 364 | } |
michael@0 | 365 | |
michael@0 | 366 | void oggpackB_adv1(oggpack_buffer *b){ |
michael@0 | 367 | oggpack_adv1(b); |
michael@0 | 368 | } |
michael@0 | 369 | |
michael@0 | 370 | /* bits <= 32 */ |
michael@0 | 371 | long oggpack_read(oggpack_buffer *b,int bits){ |
michael@0 | 372 | long ret; |
michael@0 | 373 | unsigned long m; |
michael@0 | 374 | |
michael@0 | 375 | if(bits<0 || bits>32) goto err; |
michael@0 | 376 | m=mask[bits]; |
michael@0 | 377 | bits+=b->endbit; |
michael@0 | 378 | |
michael@0 | 379 | if(b->endbyte >= b->storage-4){ |
michael@0 | 380 | /* not the main path */ |
michael@0 | 381 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; |
michael@0 | 382 | /* special case to avoid reading b->ptr[0], which might be past the end of |
michael@0 | 383 | the buffer; also skips some useless accounting */ |
michael@0 | 384 | else if(!bits)return(0L); |
michael@0 | 385 | } |
michael@0 | 386 | |
michael@0 | 387 | ret=b->ptr[0]>>b->endbit; |
michael@0 | 388 | if(bits>8){ |
michael@0 | 389 | ret|=b->ptr[1]<<(8-b->endbit); |
michael@0 | 390 | if(bits>16){ |
michael@0 | 391 | ret|=b->ptr[2]<<(16-b->endbit); |
michael@0 | 392 | if(bits>24){ |
michael@0 | 393 | ret|=b->ptr[3]<<(24-b->endbit); |
michael@0 | 394 | if(bits>32 && b->endbit){ |
michael@0 | 395 | ret|=b->ptr[4]<<(32-b->endbit); |
michael@0 | 396 | } |
michael@0 | 397 | } |
michael@0 | 398 | } |
michael@0 | 399 | } |
michael@0 | 400 | ret&=m; |
michael@0 | 401 | b->ptr+=bits/8; |
michael@0 | 402 | b->endbyte+=bits/8; |
michael@0 | 403 | b->endbit=bits&7; |
michael@0 | 404 | return ret; |
michael@0 | 405 | |
michael@0 | 406 | overflow: |
michael@0 | 407 | err: |
michael@0 | 408 | b->ptr=NULL; |
michael@0 | 409 | b->endbyte=b->storage; |
michael@0 | 410 | b->endbit=1; |
michael@0 | 411 | return -1L; |
michael@0 | 412 | } |
michael@0 | 413 | |
michael@0 | 414 | /* bits <= 32 */ |
michael@0 | 415 | long oggpackB_read(oggpack_buffer *b,int bits){ |
michael@0 | 416 | long ret; |
michael@0 | 417 | long m=32-bits; |
michael@0 | 418 | |
michael@0 | 419 | if(m<0 || m>32) goto err; |
michael@0 | 420 | bits+=b->endbit; |
michael@0 | 421 | |
michael@0 | 422 | if(b->endbyte+4>=b->storage){ |
michael@0 | 423 | /* not the main path */ |
michael@0 | 424 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; |
michael@0 | 425 | /* special case to avoid reading b->ptr[0], which might be past the end of |
michael@0 | 426 | the buffer; also skips some useless accounting */ |
michael@0 | 427 | else if(!bits)return(0L); |
michael@0 | 428 | } |
michael@0 | 429 | |
michael@0 | 430 | ret=b->ptr[0]<<(24+b->endbit); |
michael@0 | 431 | if(bits>8){ |
michael@0 | 432 | ret|=b->ptr[1]<<(16+b->endbit); |
michael@0 | 433 | if(bits>16){ |
michael@0 | 434 | ret|=b->ptr[2]<<(8+b->endbit); |
michael@0 | 435 | if(bits>24){ |
michael@0 | 436 | ret|=b->ptr[3]<<(b->endbit); |
michael@0 | 437 | if(bits>32 && b->endbit) |
michael@0 | 438 | ret|=b->ptr[4]>>(8-b->endbit); |
michael@0 | 439 | } |
michael@0 | 440 | } |
michael@0 | 441 | } |
michael@0 | 442 | ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); |
michael@0 | 443 | |
michael@0 | 444 | b->ptr+=bits/8; |
michael@0 | 445 | b->endbyte+=bits/8; |
michael@0 | 446 | b->endbit=bits&7; |
michael@0 | 447 | return ret; |
michael@0 | 448 | |
michael@0 | 449 | overflow: |
michael@0 | 450 | err: |
michael@0 | 451 | b->ptr=NULL; |
michael@0 | 452 | b->endbyte=b->storage; |
michael@0 | 453 | b->endbit=1; |
michael@0 | 454 | return -1L; |
michael@0 | 455 | } |
michael@0 | 456 | |
michael@0 | 457 | long oggpack_read1(oggpack_buffer *b){ |
michael@0 | 458 | long ret; |
michael@0 | 459 | |
michael@0 | 460 | if(b->endbyte >= b->storage) goto overflow; |
michael@0 | 461 | ret=(b->ptr[0]>>b->endbit)&1; |
michael@0 | 462 | |
michael@0 | 463 | b->endbit++; |
michael@0 | 464 | if(b->endbit>7){ |
michael@0 | 465 | b->endbit=0; |
michael@0 | 466 | b->ptr++; |
michael@0 | 467 | b->endbyte++; |
michael@0 | 468 | } |
michael@0 | 469 | return ret; |
michael@0 | 470 | |
michael@0 | 471 | overflow: |
michael@0 | 472 | b->ptr=NULL; |
michael@0 | 473 | b->endbyte=b->storage; |
michael@0 | 474 | b->endbit=1; |
michael@0 | 475 | return -1L; |
michael@0 | 476 | } |
michael@0 | 477 | |
michael@0 | 478 | long oggpackB_read1(oggpack_buffer *b){ |
michael@0 | 479 | long ret; |
michael@0 | 480 | |
michael@0 | 481 | if(b->endbyte >= b->storage) goto overflow; |
michael@0 | 482 | ret=(b->ptr[0]>>(7-b->endbit))&1; |
michael@0 | 483 | |
michael@0 | 484 | b->endbit++; |
michael@0 | 485 | if(b->endbit>7){ |
michael@0 | 486 | b->endbit=0; |
michael@0 | 487 | b->ptr++; |
michael@0 | 488 | b->endbyte++; |
michael@0 | 489 | } |
michael@0 | 490 | return ret; |
michael@0 | 491 | |
michael@0 | 492 | overflow: |
michael@0 | 493 | b->ptr=NULL; |
michael@0 | 494 | b->endbyte=b->storage; |
michael@0 | 495 | b->endbit=1; |
michael@0 | 496 | return -1L; |
michael@0 | 497 | } |
michael@0 | 498 | |
michael@0 | 499 | long oggpack_bytes(oggpack_buffer *b){ |
michael@0 | 500 | return(b->endbyte+(b->endbit+7)/8); |
michael@0 | 501 | } |
michael@0 | 502 | |
michael@0 | 503 | long oggpack_bits(oggpack_buffer *b){ |
michael@0 | 504 | return(b->endbyte*8+b->endbit); |
michael@0 | 505 | } |
michael@0 | 506 | |
michael@0 | 507 | long oggpackB_bytes(oggpack_buffer *b){ |
michael@0 | 508 | return oggpack_bytes(b); |
michael@0 | 509 | } |
michael@0 | 510 | |
michael@0 | 511 | long oggpackB_bits(oggpack_buffer *b){ |
michael@0 | 512 | return oggpack_bits(b); |
michael@0 | 513 | } |
michael@0 | 514 | |
michael@0 | 515 | unsigned char *oggpack_get_buffer(oggpack_buffer *b){ |
michael@0 | 516 | return(b->buffer); |
michael@0 | 517 | } |
michael@0 | 518 | |
michael@0 | 519 | unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ |
michael@0 | 520 | return oggpack_get_buffer(b); |
michael@0 | 521 | } |
michael@0 | 522 | |
michael@0 | 523 | /* Self test of the bitwise routines; everything else is based on |
michael@0 | 524 | them, so they damned well better be solid. */ |
michael@0 | 525 | |
michael@0 | 526 | #ifdef _V_SELFTEST |
michael@0 | 527 | #include <stdio.h> |
michael@0 | 528 | |
michael@0 | 529 | static int ilog(unsigned int v){ |
michael@0 | 530 | int ret=0; |
michael@0 | 531 | while(v){ |
michael@0 | 532 | ret++; |
michael@0 | 533 | v>>=1; |
michael@0 | 534 | } |
michael@0 | 535 | return(ret); |
michael@0 | 536 | } |
michael@0 | 537 | |
michael@0 | 538 | oggpack_buffer o; |
michael@0 | 539 | oggpack_buffer r; |
michael@0 | 540 | |
michael@0 | 541 | void report(char *in){ |
michael@0 | 542 | fprintf(stderr,"%s",in); |
michael@0 | 543 | exit(1); |
michael@0 | 544 | } |
michael@0 | 545 | |
michael@0 | 546 | void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ |
michael@0 | 547 | long bytes,i; |
michael@0 | 548 | unsigned char *buffer; |
michael@0 | 549 | |
michael@0 | 550 | oggpack_reset(&o); |
michael@0 | 551 | for(i=0;i<vals;i++) |
michael@0 | 552 | oggpack_write(&o,b[i],bits?bits:ilog(b[i])); |
michael@0 | 553 | buffer=oggpack_get_buffer(&o); |
michael@0 | 554 | bytes=oggpack_bytes(&o); |
michael@0 | 555 | if(bytes!=compsize)report("wrong number of bytes!\n"); |
michael@0 | 556 | for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ |
michael@0 | 557 | for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); |
michael@0 | 558 | report("wrote incorrect value!\n"); |
michael@0 | 559 | } |
michael@0 | 560 | oggpack_readinit(&r,buffer,bytes); |
michael@0 | 561 | for(i=0;i<vals;i++){ |
michael@0 | 562 | int tbit=bits?bits:ilog(b[i]); |
michael@0 | 563 | if(oggpack_look(&r,tbit)==-1) |
michael@0 | 564 | report("out of data!\n"); |
michael@0 | 565 | if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit])) |
michael@0 | 566 | report("looked at incorrect value!\n"); |
michael@0 | 567 | if(tbit==1) |
michael@0 | 568 | if(oggpack_look1(&r)!=(b[i]&mask[tbit])) |
michael@0 | 569 | report("looked at single bit incorrect value!\n"); |
michael@0 | 570 | if(tbit==1){ |
michael@0 | 571 | if(oggpack_read1(&r)!=(b[i]&mask[tbit])) |
michael@0 | 572 | report("read incorrect single bit value!\n"); |
michael@0 | 573 | }else{ |
michael@0 | 574 | if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit])) |
michael@0 | 575 | report("read incorrect value!\n"); |
michael@0 | 576 | } |
michael@0 | 577 | } |
michael@0 | 578 | if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
michael@0 | 579 | } |
michael@0 | 580 | |
michael@0 | 581 | void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ |
michael@0 | 582 | long bytes,i; |
michael@0 | 583 | unsigned char *buffer; |
michael@0 | 584 | |
michael@0 | 585 | oggpackB_reset(&o); |
michael@0 | 586 | for(i=0;i<vals;i++) |
michael@0 | 587 | oggpackB_write(&o,b[i],bits?bits:ilog(b[i])); |
michael@0 | 588 | buffer=oggpackB_get_buffer(&o); |
michael@0 | 589 | bytes=oggpackB_bytes(&o); |
michael@0 | 590 | if(bytes!=compsize)report("wrong number of bytes!\n"); |
michael@0 | 591 | for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ |
michael@0 | 592 | for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); |
michael@0 | 593 | report("wrote incorrect value!\n"); |
michael@0 | 594 | } |
michael@0 | 595 | oggpackB_readinit(&r,buffer,bytes); |
michael@0 | 596 | for(i=0;i<vals;i++){ |
michael@0 | 597 | int tbit=bits?bits:ilog(b[i]); |
michael@0 | 598 | if(oggpackB_look(&r,tbit)==-1) |
michael@0 | 599 | report("out of data!\n"); |
michael@0 | 600 | if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit])) |
michael@0 | 601 | report("looked at incorrect value!\n"); |
michael@0 | 602 | if(tbit==1) |
michael@0 | 603 | if(oggpackB_look1(&r)!=(b[i]&mask[tbit])) |
michael@0 | 604 | report("looked at single bit incorrect value!\n"); |
michael@0 | 605 | if(tbit==1){ |
michael@0 | 606 | if(oggpackB_read1(&r)!=(b[i]&mask[tbit])) |
michael@0 | 607 | report("read incorrect single bit value!\n"); |
michael@0 | 608 | }else{ |
michael@0 | 609 | if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit])) |
michael@0 | 610 | report("read incorrect value!\n"); |
michael@0 | 611 | } |
michael@0 | 612 | } |
michael@0 | 613 | if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
michael@0 | 614 | } |
michael@0 | 615 | |
michael@0 | 616 | int main(void){ |
michael@0 | 617 | unsigned char *buffer; |
michael@0 | 618 | long bytes,i; |
michael@0 | 619 | static unsigned long testbuffer1[]= |
michael@0 | 620 | {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, |
michael@0 | 621 | 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; |
michael@0 | 622 | int test1size=43; |
michael@0 | 623 | |
michael@0 | 624 | static unsigned long testbuffer2[]= |
michael@0 | 625 | {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212, |
michael@0 | 626 | 1233432,534,5,346435231,14436467,7869299,76326614,167548585, |
michael@0 | 627 | 85525151,0,12321,1,349528352}; |
michael@0 | 628 | int test2size=21; |
michael@0 | 629 | |
michael@0 | 630 | static unsigned long testbuffer3[]= |
michael@0 | 631 | {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, |
michael@0 | 632 | 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1}; |
michael@0 | 633 | int test3size=56; |
michael@0 | 634 | |
michael@0 | 635 | static unsigned long large[]= |
michael@0 | 636 | {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212, |
michael@0 | 637 | 1233432,534,5,2146435231,14436467,7869299,76326614,167548585, |
michael@0 | 638 | 85525151,0,12321,1,2146528352}; |
michael@0 | 639 | |
michael@0 | 640 | int onesize=33; |
michael@0 | 641 | static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40, |
michael@0 | 642 | 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172, |
michael@0 | 643 | 223,4}; |
michael@0 | 644 | static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222, |
michael@0 | 645 | 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18, |
michael@0 | 646 | 245,251,128}; |
michael@0 | 647 | |
michael@0 | 648 | int twosize=6; |
michael@0 | 649 | static int two[6]={61,255,255,251,231,29}; |
michael@0 | 650 | static int twoB[6]={247,63,255,253,249,120}; |
michael@0 | 651 | |
michael@0 | 652 | int threesize=54; |
michael@0 | 653 | static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254, |
michael@0 | 654 | 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83, |
michael@0 | 655 | 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10, |
michael@0 | 656 | 100,52,4,14,18,86,77,1}; |
michael@0 | 657 | static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183, |
michael@0 | 658 | 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98, |
michael@0 | 659 | 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104, |
michael@0 | 660 | 200,20,254,4,58,106,176,144,0}; |
michael@0 | 661 | |
michael@0 | 662 | int foursize=38; |
michael@0 | 663 | static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72, |
michael@0 | 664 | 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169, |
michael@0 | 665 | 28,2,133,0,1}; |
michael@0 | 666 | static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41, |
michael@0 | 667 | 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67, |
michael@0 | 668 | 129,10,4,32}; |
michael@0 | 669 | |
michael@0 | 670 | int fivesize=45; |
michael@0 | 671 | static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62, |
michael@0 | 672 | 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169, |
michael@0 | 673 | 84,75,159,2,1,0,132,192,8,0,0,18,22}; |
michael@0 | 674 | static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226, |
michael@0 | 675 | 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77, |
michael@0 | 676 | 172,150,169,129,79,128,0,6,4,32,0,27,9,0}; |
michael@0 | 677 | |
michael@0 | 678 | int sixsize=7; |
michael@0 | 679 | static int six[7]={17,177,170,242,169,19,148}; |
michael@0 | 680 | static int sixB[7]={136,141,85,79,149,200,41}; |
michael@0 | 681 | |
michael@0 | 682 | /* Test read/write together */ |
michael@0 | 683 | /* Later we test against pregenerated bitstreams */ |
michael@0 | 684 | oggpack_writeinit(&o); |
michael@0 | 685 | |
michael@0 | 686 | fprintf(stderr,"\nSmall preclipped packing (LSb): "); |
michael@0 | 687 | cliptest(testbuffer1,test1size,0,one,onesize); |
michael@0 | 688 | fprintf(stderr,"ok."); |
michael@0 | 689 | |
michael@0 | 690 | fprintf(stderr,"\nNull bit call (LSb): "); |
michael@0 | 691 | cliptest(testbuffer3,test3size,0,two,twosize); |
michael@0 | 692 | fprintf(stderr,"ok."); |
michael@0 | 693 | |
michael@0 | 694 | fprintf(stderr,"\nLarge preclipped packing (LSb): "); |
michael@0 | 695 | cliptest(testbuffer2,test2size,0,three,threesize); |
michael@0 | 696 | fprintf(stderr,"ok."); |
michael@0 | 697 | |
michael@0 | 698 | fprintf(stderr,"\n32 bit preclipped packing (LSb): "); |
michael@0 | 699 | oggpack_reset(&o); |
michael@0 | 700 | for(i=0;i<test2size;i++) |
michael@0 | 701 | oggpack_write(&o,large[i],32); |
michael@0 | 702 | buffer=oggpack_get_buffer(&o); |
michael@0 | 703 | bytes=oggpack_bytes(&o); |
michael@0 | 704 | oggpack_readinit(&r,buffer,bytes); |
michael@0 | 705 | for(i=0;i<test2size;i++){ |
michael@0 | 706 | if(oggpack_look(&r,32)==-1)report("out of data. failed!"); |
michael@0 | 707 | if(oggpack_look(&r,32)!=large[i]){ |
michael@0 | 708 | fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i], |
michael@0 | 709 | oggpack_look(&r,32),large[i]); |
michael@0 | 710 | report("read incorrect value!\n"); |
michael@0 | 711 | } |
michael@0 | 712 | oggpack_adv(&r,32); |
michael@0 | 713 | } |
michael@0 | 714 | if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
michael@0 | 715 | fprintf(stderr,"ok."); |
michael@0 | 716 | |
michael@0 | 717 | fprintf(stderr,"\nSmall unclipped packing (LSb): "); |
michael@0 | 718 | cliptest(testbuffer1,test1size,7,four,foursize); |
michael@0 | 719 | fprintf(stderr,"ok."); |
michael@0 | 720 | |
michael@0 | 721 | fprintf(stderr,"\nLarge unclipped packing (LSb): "); |
michael@0 | 722 | cliptest(testbuffer2,test2size,17,five,fivesize); |
michael@0 | 723 | fprintf(stderr,"ok."); |
michael@0 | 724 | |
michael@0 | 725 | fprintf(stderr,"\nSingle bit unclipped packing (LSb): "); |
michael@0 | 726 | cliptest(testbuffer3,test3size,1,six,sixsize); |
michael@0 | 727 | fprintf(stderr,"ok."); |
michael@0 | 728 | |
michael@0 | 729 | fprintf(stderr,"\nTesting read past end (LSb): "); |
michael@0 | 730 | oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
michael@0 | 731 | for(i=0;i<64;i++){ |
michael@0 | 732 | if(oggpack_read(&r,1)!=0){ |
michael@0 | 733 | fprintf(stderr,"failed; got -1 prematurely.\n"); |
michael@0 | 734 | exit(1); |
michael@0 | 735 | } |
michael@0 | 736 | } |
michael@0 | 737 | if(oggpack_look(&r,1)!=-1 || |
michael@0 | 738 | oggpack_read(&r,1)!=-1){ |
michael@0 | 739 | fprintf(stderr,"failed; read past end without -1.\n"); |
michael@0 | 740 | exit(1); |
michael@0 | 741 | } |
michael@0 | 742 | oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
michael@0 | 743 | if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){ |
michael@0 | 744 | fprintf(stderr,"failed 2; got -1 prematurely.\n"); |
michael@0 | 745 | exit(1); |
michael@0 | 746 | } |
michael@0 | 747 | |
michael@0 | 748 | if(oggpack_look(&r,18)!=0 || |
michael@0 | 749 | oggpack_look(&r,18)!=0){ |
michael@0 | 750 | fprintf(stderr,"failed 3; got -1 prematurely.\n"); |
michael@0 | 751 | exit(1); |
michael@0 | 752 | } |
michael@0 | 753 | if(oggpack_look(&r,19)!=-1 || |
michael@0 | 754 | oggpack_look(&r,19)!=-1){ |
michael@0 | 755 | fprintf(stderr,"failed; read past end without -1.\n"); |
michael@0 | 756 | exit(1); |
michael@0 | 757 | } |
michael@0 | 758 | if(oggpack_look(&r,32)!=-1 || |
michael@0 | 759 | oggpack_look(&r,32)!=-1){ |
michael@0 | 760 | fprintf(stderr,"failed; read past end without -1.\n"); |
michael@0 | 761 | exit(1); |
michael@0 | 762 | } |
michael@0 | 763 | oggpack_writeclear(&o); |
michael@0 | 764 | fprintf(stderr,"ok.\n"); |
michael@0 | 765 | |
michael@0 | 766 | /********** lazy, cut-n-paste retest with MSb packing ***********/ |
michael@0 | 767 | |
michael@0 | 768 | /* Test read/write together */ |
michael@0 | 769 | /* Later we test against pregenerated bitstreams */ |
michael@0 | 770 | oggpackB_writeinit(&o); |
michael@0 | 771 | |
michael@0 | 772 | fprintf(stderr,"\nSmall preclipped packing (MSb): "); |
michael@0 | 773 | cliptestB(testbuffer1,test1size,0,oneB,onesize); |
michael@0 | 774 | fprintf(stderr,"ok."); |
michael@0 | 775 | |
michael@0 | 776 | fprintf(stderr,"\nNull bit call (MSb): "); |
michael@0 | 777 | cliptestB(testbuffer3,test3size,0,twoB,twosize); |
michael@0 | 778 | fprintf(stderr,"ok."); |
michael@0 | 779 | |
michael@0 | 780 | fprintf(stderr,"\nLarge preclipped packing (MSb): "); |
michael@0 | 781 | cliptestB(testbuffer2,test2size,0,threeB,threesize); |
michael@0 | 782 | fprintf(stderr,"ok."); |
michael@0 | 783 | |
michael@0 | 784 | fprintf(stderr,"\n32 bit preclipped packing (MSb): "); |
michael@0 | 785 | oggpackB_reset(&o); |
michael@0 | 786 | for(i=0;i<test2size;i++) |
michael@0 | 787 | oggpackB_write(&o,large[i],32); |
michael@0 | 788 | buffer=oggpackB_get_buffer(&o); |
michael@0 | 789 | bytes=oggpackB_bytes(&o); |
michael@0 | 790 | oggpackB_readinit(&r,buffer,bytes); |
michael@0 | 791 | for(i=0;i<test2size;i++){ |
michael@0 | 792 | if(oggpackB_look(&r,32)==-1)report("out of data. failed!"); |
michael@0 | 793 | if(oggpackB_look(&r,32)!=large[i]){ |
michael@0 | 794 | fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i], |
michael@0 | 795 | oggpackB_look(&r,32),large[i]); |
michael@0 | 796 | report("read incorrect value!\n"); |
michael@0 | 797 | } |
michael@0 | 798 | oggpackB_adv(&r,32); |
michael@0 | 799 | } |
michael@0 | 800 | if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
michael@0 | 801 | fprintf(stderr,"ok."); |
michael@0 | 802 | |
michael@0 | 803 | fprintf(stderr,"\nSmall unclipped packing (MSb): "); |
michael@0 | 804 | cliptestB(testbuffer1,test1size,7,fourB,foursize); |
michael@0 | 805 | fprintf(stderr,"ok."); |
michael@0 | 806 | |
michael@0 | 807 | fprintf(stderr,"\nLarge unclipped packing (MSb): "); |
michael@0 | 808 | cliptestB(testbuffer2,test2size,17,fiveB,fivesize); |
michael@0 | 809 | fprintf(stderr,"ok."); |
michael@0 | 810 | |
michael@0 | 811 | fprintf(stderr,"\nSingle bit unclipped packing (MSb): "); |
michael@0 | 812 | cliptestB(testbuffer3,test3size,1,sixB,sixsize); |
michael@0 | 813 | fprintf(stderr,"ok."); |
michael@0 | 814 | |
michael@0 | 815 | fprintf(stderr,"\nTesting read past end (MSb): "); |
michael@0 | 816 | oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
michael@0 | 817 | for(i=0;i<64;i++){ |
michael@0 | 818 | if(oggpackB_read(&r,1)!=0){ |
michael@0 | 819 | fprintf(stderr,"failed; got -1 prematurely.\n"); |
michael@0 | 820 | exit(1); |
michael@0 | 821 | } |
michael@0 | 822 | } |
michael@0 | 823 | if(oggpackB_look(&r,1)!=-1 || |
michael@0 | 824 | oggpackB_read(&r,1)!=-1){ |
michael@0 | 825 | fprintf(stderr,"failed; read past end without -1.\n"); |
michael@0 | 826 | exit(1); |
michael@0 | 827 | } |
michael@0 | 828 | oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
michael@0 | 829 | if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){ |
michael@0 | 830 | fprintf(stderr,"failed 2; got -1 prematurely.\n"); |
michael@0 | 831 | exit(1); |
michael@0 | 832 | } |
michael@0 | 833 | |
michael@0 | 834 | if(oggpackB_look(&r,18)!=0 || |
michael@0 | 835 | oggpackB_look(&r,18)!=0){ |
michael@0 | 836 | fprintf(stderr,"failed 3; got -1 prematurely.\n"); |
michael@0 | 837 | exit(1); |
michael@0 | 838 | } |
michael@0 | 839 | if(oggpackB_look(&r,19)!=-1 || |
michael@0 | 840 | oggpackB_look(&r,19)!=-1){ |
michael@0 | 841 | fprintf(stderr,"failed; read past end without -1.\n"); |
michael@0 | 842 | exit(1); |
michael@0 | 843 | } |
michael@0 | 844 | if(oggpackB_look(&r,32)!=-1 || |
michael@0 | 845 | oggpackB_look(&r,32)!=-1){ |
michael@0 | 846 | fprintf(stderr,"failed; read past end without -1.\n"); |
michael@0 | 847 | exit(1); |
michael@0 | 848 | } |
michael@0 | 849 | oggpackB_writeclear(&o); |
michael@0 | 850 | fprintf(stderr,"ok.\n\n"); |
michael@0 | 851 | |
michael@0 | 852 | |
michael@0 | 853 | return(0); |
michael@0 | 854 | } |
michael@0 | 855 | #endif /* _V_SELFTEST */ |
michael@0 | 856 | |
michael@0 | 857 | #undef BUFFER_INCREMENT |