[xiph-cvs] cvs commit: ogg/src bitwise.c

Monty xiphmont at xiph.org
Tue Feb 4 22:42:28 PST 2003



xiphmont    03/02/05 01:42:28

  Modified:    src      Tag: libogg2-zerocopy bitwise.c
  Log:
  bitwise coonversion to zero copy complete with full unit tests.
  
  Monty

Revision  Changes    Path
No                   revision

<p>No                   revision

<p>1.14.2.6  +333 -11   ogg/src/bitwise.c

Index: bitwise.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/bitwise.c,v
retrieving revision 1.14.2.5
retrieving revision 1.14.2.6
diff -u -r1.14.2.5 -r1.14.2.6
--- bitwise.c	3 Feb 2003 23:01:47 -0000	1.14.2.5
+++ bitwise.c	5 Feb 2003 06:42:28 -0000	1.14.2.6
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: pack variable sized words into an octet stream
-  last mod: $Id: bitwise.c,v 1.14.2.5 2003/02/03 23:01:47 xiphmont Exp $
+  last mod: $Id: bitwise.c,v 1.14.2.6 2003/02/05 06:42:28 xiphmont Exp $
 
  ********************************************************************/
 
@@ -213,7 +213,7 @@
   b->headptr=b->head->data+begin;
 
   if(b->head->used>b->length){
-    b->headend=b->length;
+    b->headend=b->length-begin;
   }else{
     b->headend=b->head->used-begin;
   }
@@ -469,7 +469,11 @@
     b->count+=b->head->used;
     b->length-=b->head->used;
     b->head=b->head->next;
-    b->headend+=b->head->used;
+
+    if(b->length<b->head->used)
+      b->headend+=b->length;
+    else
+      b->headend+=b->head->used;
 
   }else{
   
@@ -544,7 +548,10 @@
     b->count+=b->head->used;
     b->length-=b->head->used;
     b->head=b->head->next;
-    b->headend+=b->head->used;
+    if(b->length<b->head->used)
+      b->headend+=b->length;
+    else
+      b->headend+=b->head->used;
     
   }else{
   
@@ -812,6 +819,45 @@
 
 }
 
+void msbverify(unsigned long *values,int *len,unsigned char *flat) {
+  int j,k;
+  int flatbyte=0;
+  int flatbit=0;
+  
+  /* verify written buffer is correct bit-by-bit */
+  for(j=0;j<TESTWORDS;j++){
+    for(k=0;k<len[j];k++){
+      int origbit=(values[j]>>(len[j]-k-1))&1;
+      int bit=(flat[flatbyte]>>(7-flatbit))&1;
+      flatbit++;
+      if(flatbit>7){
+	flatbit=0;
+	++flatbyte;
+      }
+      
+      if(origbit!=bit){
+	fprintf(stderr,"\n\tERROR: bit mismatch!  "
+		"word %d, bit %d, value %lx, len %d\n",
+		j,k,values[j],len[j]);
+	exit(1);
+      }
+      
+    }
+  }
+
+  /* verify that trailing packing is zeroed */
+  while(flatbit && flatbit<8){
+    int bit=(flat[flatbyte]>>(7-flatbit++))&1;
+  
+    if(0!=bit){
+      fprintf(stderr,"\n\tERROR: trailing byte padding not zero!\n");
+      exit(1);
+    }
+  }  
+  
+
+}
+
 int main(void){
   long bytes,i;
   static unsigned long testbuffer1[]=
@@ -1071,7 +1117,7 @@
   /* now the scary shit: randomized testing */
 
   for(i=0;i<1000;i++){
-    int j,count=0,count2=0;
+    int j,count=0,count2=0,bitcount=0;
     unsigned long values[TESTWORDS];
     int len[TESTWORDS];
     unsigned char flat[4*TESTWORDS]; /* max possible needed size */
@@ -1085,11 +1131,26 @@
       values[j]=rand();
       len[j]=(rand()%32)+1;
       count+=len[j];
+
       oggpack_write(&o,values[j],len[j]);
+
+      bitcount+=len[j];
+      if(oggpack_bits(&o)!=bitcount){
+	fprintf(stderr,"\nERROR: Write bitcounter %d != %ld!\n",
+		bitcount,oggpack_bits(&o));
+	exit(1);
+      }
+      if(oggpack_bytes(&o)!=(bitcount+7)/8){
+	fprintf(stderr,"\nERROR: Write bytecounter %d != %ld!\n",
+		(bitcount+7)/8,oggpack_bytes(&o));
+	exit(1);
+      }
+      
     }
 
     /* flatten the packbuffer out to a vector */
     count2=flatten(flat);
+    oggpackB_writeclear(&o);
 
     /* verify against original list */
     lsbverify(values,len,flat);
@@ -1140,12 +1201,69 @@
 
         oggpack_readinit(&o,&or);
 
-	for(j=0;j<bitoffset;j++)
-	  oggpack_read1(&o);
-	
+	/* verify bit count */
+	if(oggpack_bits(&o)!=0){
+	  fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
+	  exit(1);
+	}
+	if(oggpack_bytes(&o)!=0){
+	  fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
+	  exit(1);
+	}
+
+	bitcount=bitoffset;
+	oggpack_read(&o,bitoffset,&temp);
+
         /* read and compare to original list */
         for(j=begin;j<begin+ilen;j++){
-	  if(oggpack_read(&o,len[j],&temp)){
+	  int ret;
+	  if(len[j]==1 && rand()%1)
+	    temp=ret=oggpack_read1(&o);
+	  else
+	    ret=oggpack_read(&o,len[j],&temp);
+	  if(ret<0){
+	    fprintf(stderr,"\nERROR: End of stream too soon! word: %d\n",
+		    j-begin);
+	    exit(1);
+	  }
+	  if(temp!=(values[j]&mask[len[j]])){
+	    fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
+		    values[j]&mask[len[j]],temp,j-begin,len[j]);
+	    exit(1);
+	  }
+	  bitcount+=len[j];
+	  if(oggpack_bits(&o)!=bitcount){
+	    fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
+		    bitcount,oggpack_bits(&o));
+	    exit(1);
+	  }
+	  if(oggpack_bytes(&o)!=(bitcount+7)/8){
+	    fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
+		    (bitcount+7)/8,oggpack_bytes(&o));
+	    exit(1);
+	  }
+	  
+	}
+	/* are we on our last byte as predicted? */
+	if(!oggpack_read(&o,8,&temp)){
+	    fprintf(stderr,"\nERROR: Excess buffer data after read\n");
+	    exit(1);
+	}	
+
+	/* look/adv version */
+	oggpack_readinit(&o,&or);
+	bitcount=bitoffset;
+	oggpack_adv(&o,bitoffset);
+
+	/* read and compare to original list */
+	for(j=begin;j<begin+ilen;j++){
+	  int ret;
+	  if(len[j]==1 && rand()%1)
+	    temp=ret=oggpack_look1(&o);
+	  else
+	    ret=oggpack_look(&o,len[j],&temp);
+
+	  if(ret<0){
             fprintf(stderr,"\nERROR: End of stream too soon! word: %d\n",
                     j-begin);
             exit(1);
@@ -1155,14 +1273,218 @@
                     values[j]&mask[len[j]],temp,j-begin,len[j]);
             exit(1);
           }
+	  if(len[j]==1 && rand()%1)
+	    oggpack_adv1(&o);
+	  else
+	    oggpack_adv(&o,len[j]);
+	  bitcount+=len[j];
+	  if(oggpack_bits(&o)!=bitcount){
+	    fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
+		    bitcount,oggpack_bits(&o));
+	    exit(1);
+	  }
+	  if(oggpack_bytes(&o)!=(bitcount+7)/8){
+	    fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
+		    (bitcount+7)/8,oggpack_bytes(&o));
+	    exit(1);
+	  }
+	  
         }
+	/* are we on our last byte as predicted? */
+	if(!oggpack_read(&o,8,&temp)){
+	    fprintf(stderr,"\nERROR: Excess buffer data after read\n");
+	    exit(1);
+	}	
+
       }
     }
-    oggpack_writeinit(&o,&bs);
   }
-  fprintf(stderr,"\rRandomized n-bit testing (LSb)... ok.   \n");
+  fprintf(stderr,"\rRandomized testing (LSb)... ok.   \n");
 
-  oggpackB_writeclear(&o);
+  for(i=0;i<1000;i++){
+    int j,count=0,count2=0,bitcount=0;
+    unsigned long values[TESTWORDS];
+    int len[TESTWORDS];
+    unsigned char flat[4*TESTWORDS]; /* max possible needed size */
+
+    fprintf(stderr,"\rRandomized testing (MSb)... (%ld)   ",1000-i);
+    oggpackB_writeinit(&o,&bs);
+
+    /* generate a list of words and lengths */
+    /* write the required number of bits out to packbuffer */
+    for(j=0;j<TESTWORDS;j++){
+      values[j]=rand();
+      len[j]=(rand()%32)+1;
+      count+=len[j];
+
+      oggpackB_write(&o,values[j],len[j]);
+
+      bitcount+=len[j];
+      if(oggpackB_bits(&o)!=bitcount){
+	fprintf(stderr,"\nERROR: Write bitcounter %d != %ld!\n",
+		bitcount,oggpackB_bits(&o));
+	exit(1);
+      }
+      if(oggpackB_bytes(&o)!=(bitcount+7)/8){
+	fprintf(stderr,"\nERROR: Write bytecounter %d != %ld!\n",
+		(bitcount+7)/8,oggpackB_bytes(&o));
+	exit(1);
+      }
+      
+    }
+
+    /* flatten the packbuffer out to a vector */
+    count2=flatten(flat);
+    oggpackB_writeclear(&o);
+
+    /* verify against original list */
+    msbverify(values,len,flat);
+
+    /* construct random-length buffer chain from flat vector; random
+       byte starting offset within the length of the vector */
+    {
+      ogg_buffer *obl=NULL,*ob=NULL;
+      unsigned char *ptr=flat;
+      
+      /* build buffer chain */
+      while(count2){
+	int ilen;
+	ogg_buffer *temp=_ogg_malloc(sizeof(*temp)); /* we don't bother
+                                                      freeing later;
+                                                      this is just a
+                                                      unit test */
+	if(obl)
+	  obl->next=temp;
+	else
+	  ob=temp;
+
+	ilen=(rand()%8)*4+4;
+	if(ilen>count2)ilen=count2;
+	obl=temp;
+	obl->data=ptr;
+	obl->size=count2;
+	obl->used=ilen;
+	
+	count2-=ilen;
+	ptr+=ilen;
+      }
+      /* build reference; choose a starting offset. */
+      {
+	int begin=(rand()%TESTWORDS);
+	int ilen=(rand()%(TESTWORDS-begin));
+	int bitoffset,bitcount=0;
+	unsigned long temp;
+	or.buffer=ob;
+
+	for(j=0;j<begin;j++)
+	  bitcount+=len[j];
+	or.begin=bitcount/8;
+	bitoffset=bitcount%8;
+	for(;j<begin+ilen;j++)
+	  bitcount+=len[j];
+	or.length=((bitcount+7)/8)-or.begin;
+
+	oggpackB_readinit(&o,&or);
+
+	/* verify bit count */
+	if(oggpackB_bits(&o)!=0){
+	  fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
+	  exit(1);
+	}
+	if(oggpackB_bytes(&o)!=0){
+	  fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
+	  exit(1);
+	}
+
+	bitcount=bitoffset;
+	oggpackB_read(&o,bitoffset,&temp);
+
+	/* read and compare to original list */
+	for(j=begin;j<begin+ilen;j++){
+	  int ret;
+	  if(len[j]==1 && rand()%1)
+	    temp=ret=oggpackB_read1(&o);
+	  else
+	    ret=oggpackB_read(&o,len[j],&temp);
+	  if(ret<0){
+	    fprintf(stderr,"\nERROR: End of stream too soon! word: %d\n",
+		    j-begin);
+	    exit(1);
+	  }
+	  if(temp!=(values[j]&mask[len[j]])){
+	    fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
+		    values[j]&mask[len[j]],temp,j-begin,len[j]);
+	    exit(1);
+	  }
+	  bitcount+=len[j];
+	  if(oggpackB_bits(&o)!=bitcount){
+	    fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
+		    bitcount,oggpackB_bits(&o));
+	    exit(1);
+	  }
+	  if(oggpackB_bytes(&o)!=(bitcount+7)/8){
+	    fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
+		    (bitcount+7)/8,oggpackB_bytes(&o));
+	    exit(1);
+	  }
+	  
+	}
+	/* are we on our last byte as predicted? */
+	if(!oggpackB_read(&o,8,&temp)){
+	    fprintf(stderr,"\nERROR: Excess buffer data after read\n");
+	    exit(1);
+	}	
+
+	/* look/adv version */
+	oggpackB_readinit(&o,&or);
+	bitcount=bitoffset;
+	oggpackB_adv(&o,bitoffset);
+
+	/* read and compare to original list */
+	for(j=begin;j<begin+ilen;j++){
+	  int ret;
+	  if(len[j]==1 && rand()%1)
+	    temp=ret=oggpackB_look1(&o);
+	  else
+	    ret=oggpackB_look(&o,len[j],&temp);
+
+	  if(ret<0){
+	    fprintf(stderr,"\nERROR: End of stream too soon! word: %d\n",
+		    j-begin);
+	    exit(1);
+	  }
+	  if(temp!=(values[j]&mask[len[j]])){
+	    fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
+		    values[j]&mask[len[j]],temp,j-begin,len[j]);
+	    exit(1);
+	  }
+	  if(len[j]==1 && rand()%1)
+	    oggpackB_adv1(&o);
+	  else
+	    oggpackB_adv(&o,len[j]);
+	  bitcount+=len[j];
+	  if(oggpackB_bits(&o)!=bitcount){
+	    fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
+		    bitcount,oggpackB_bits(&o));
+	    exit(1);
+	  }
+	  if(oggpackB_bytes(&o)!=(bitcount+7)/8){
+	    fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
+		    (bitcount+7)/8,oggpackB_bytes(&o));
+	    exit(1);
+	  }
+	  
+	}
+	/* are we on our last byte as predicted? */
+	if(!oggpackB_read(&o,8,&temp)){
+	    fprintf(stderr,"\nERROR: Excess buffer data after read\n");
+	    exit(1);
+	}	
+
+      }
+    }
+  }
+  fprintf(stderr,"\rRandomized testing (MSb)... ok.   \n");
 
   ogg_buffer_clear(&bs);
   return(0);

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list