Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
bitio.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 #include <assert.h>
00095 #include "all.h"
00096 #include "byteorder.h"
00097 #include "bitio.h"
00098 #include "mtypes.h"
00099 
00100 
00101 
00102 
00103 
00104  
00105 static void Dump _ANSI_ARGS_((BitBucket *bbPtr));
00106 
00107 
00108 
00109 
00110 
00111 
00112 static uint32 lower_mask[33] = {
00113     0,
00114     0x1, 0x3, 0x7, 0xf,
00115     0x1f, 0x3f, 0x7f, 0xff,
00116     0x1ff, 0x3ff, 0x7ff, 0xfff,
00117     0x1fff, 0x3fff, 0x7fff, 0xffff,
00118     0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
00119     0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
00120     0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
00121     0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
00122 };
00123 
00124 
00125 extern time_t IOtime;
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 BitBucket *
00146 Bitio_New(filePtr)
00147     FILE *filePtr;
00148 {
00149     BitBucket *bbPtr;
00150 
00151     bbPtr = (BitBucket *) malloc(sizeof(BitBucket));
00152     ERRCHK(bbPtr, "malloc");
00153 
00154     bbPtr->firstPtr = bbPtr->lastPtr = (struct bitBucket *) malloc(sizeof(struct bitBucket));
00155     ERRCHK(bbPtr->firstPtr, "malloc");
00156 
00157     bbPtr->totalbits = 0;
00158     bbPtr->cumulativeBits = 0;
00159     bbPtr->bitsWritten = 0;
00160     bbPtr->filePtr = filePtr;
00161 
00162     bbPtr->firstPtr->nextPtr = NULL;
00163     bbPtr->firstPtr->bitsleft = MAXBITS_PER_BUCKET;
00164     bbPtr->firstPtr->bitsleftcur = 32;
00165     bbPtr->firstPtr->currword = 0;
00166     memset((char *)bbPtr->firstPtr->bits, 0, sizeof(uint32) * WORDS_PER_BUCKET);
00167 
00168     return bbPtr;
00169 }
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 void
00184 Bitio_Free(bbPtr)
00185     BitBucket *bbPtr;
00186 {
00187     struct bitBucket *tmpPtr, *nextPtr;
00188 
00189     for (tmpPtr = bbPtr->firstPtr; tmpPtr != NULL; tmpPtr = nextPtr) {
00190         nextPtr = tmpPtr->nextPtr;
00191         free(tmpPtr);
00192     }
00193     free(bbPtr);
00194 }
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 void
00212 Bitio_Write(bbPtr, bits, nbits)
00213     BitBucket *bbPtr;
00214     uint32 bits;
00215     int nbits;
00216 {
00217     register struct bitBucket *lastPtr, *newPtr;
00218     register int delta;
00219 
00220     assert(nbits <= 32 && nbits >= 0);
00221 
00222     
00223 
00224 
00225 
00226 
00227     bits = bits & lower_mask[nbits];
00228 
00229     bbPtr->totalbits += nbits;
00230     bbPtr->cumulativeBits += nbits;
00231     lastPtr = bbPtr->lastPtr;
00232 
00233     delta = nbits - lastPtr->bitsleft;
00234     if (delta >= 0) {
00235         
00236 
00237 
00238 
00239         newPtr = lastPtr->nextPtr = (struct bitBucket *) malloc(sizeof(struct bitBucket));
00240         ERRCHK(newPtr, "malloc");
00241         newPtr->nextPtr = NULL;
00242         newPtr->bitsleft = MAXBITS_PER_BUCKET;
00243         newPtr->bitsleftcur = 32;
00244         newPtr->currword = 0;
00245         memset((char *)newPtr->bits, 0, sizeof(uint32) * WORDS_PER_BUCKET);
00246         bbPtr->lastPtr = newPtr;
00247 
00248         assert(lastPtr->currword == WORDS_PER_BUCKET - 1);
00249         lastPtr->bits[WORDS_PER_BUCKET - 1] |= (bits >> delta);
00250         lastPtr->bitsleft = 0;
00251         lastPtr->bitsleftcur = 0;
00252         
00253 
00254         if (!delta) {
00255             if ( bbPtr->totalbits > MAX_BITS ) {
00256                 Dump(bbPtr);
00257             }
00258         }
00259 
00260         assert(delta <= 32);
00261         newPtr->bits[0] = (bits & lower_mask[delta]) << (32 - delta);
00262         newPtr->bitsleft -= delta;
00263         newPtr->bitsleftcur -= delta;
00264     } else {
00265         
00266 
00267 
00268         delta = nbits - lastPtr->bitsleftcur;
00269         lastPtr->bitsleftcur -= nbits;
00270         lastPtr->bitsleft -= nbits;
00271 
00272         if (delta >= 0)
00273         {
00274             
00275 
00276 
00277             lastPtr->bits[lastPtr->currword] |= (bits >> delta);
00278             lastPtr->currword++;
00279             lastPtr->bits[lastPtr->currword] = (bits & lower_mask[delta]) << (32 - delta);
00280             lastPtr->bitsleftcur = 32 - delta;
00281         } else {
00282             
00283 
00284 
00285             lastPtr->bits[lastPtr->currword] |= (bits << (-delta));
00286         }
00287     }
00288 
00289     if ( bbPtr->totalbits > MAX_BITS )  
00290         Dump(bbPtr);
00291 }
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 void
00309 Bitio_Flush(bbPtr)
00310     BitBucket *bbPtr;
00311 {
00312     struct bitBucket *ptr, *tempPtr;
00313     uint32 buffer[WORDS_PER_BUCKET];
00314     uint32  lastWord;
00315     int i, nitems;
00316     int     bitsWritten = 0;
00317     int     bitsLeft;
00318     int     numWords;
00319     uint8   charBuf[4];
00320     boolean    flushHere = FALSE;
00321     time_t  tempTimeStart, tempTimeEnd;
00322 
00323     time(&tempTimeStart);
00324 
00325     bitsLeft = bbPtr->totalbits;
00326 
00327     for (ptr = bbPtr->firstPtr; ptr; ptr = ptr->nextPtr) {
00328         if (ptr->bitsleftcur == 32 && ptr->currword == 0) {
00329             continue;           
00330         }
00331 
00332         if ( bitsLeft >= 32 ) {
00333             if ( ((ptr->currword + 1) * 32) > bitsLeft ) {
00334                 numWords = ptr->currword;
00335                 flushHere = TRUE;
00336             } else {
00337                 numWords = ptr->currword+1;
00338             }
00339 
00340             for (i = 0; i < numWords; i++) {
00341                 buffer[i] = htonl(ptr->bits[i]);
00342             }
00343 
00344             nitems = fwrite(buffer, sizeof(uint32), numWords, bbPtr->filePtr);
00345             if (nitems != numWords) {
00346                 fprintf(stderr, "Whoa!  Trouble writing %d bytes (got %d items)!  Game over, dude!\n",
00347                         (int)(numWords), nitems);
00348                 exit(1);
00349             }
00350 
00351             bitsWritten += (numWords * 32);
00352             bitsLeft -= (numWords * 32);
00353         } else {
00354             flushHere = TRUE;
00355         }
00356 
00357         if ( (bitsLeft < 32) && flushHere ) {
00358             lastWord = ptr->bits[ptr->currword];
00359 
00360             
00361 
00362             
00363             while ( bitsLeft > 0 ) {
00364                 charBuf[0] = (lastWord >> 24);
00365                 charBuf[0] &= lower_mask[8];
00366                 fwrite(charBuf, 1, sizeof(uint8), bbPtr->filePtr);
00367                 lastWord = (lastWord << 8);
00368                 bitsLeft -= 8;
00369                 bitsWritten += 8;
00370             }
00371         }
00372     }
00373     fflush(bbPtr->filePtr);
00374     while ( bbPtr->firstPtr != ptr ) {
00375         tempPtr = bbPtr->firstPtr;
00376         bbPtr->firstPtr = tempPtr->nextPtr;
00377         free(tempPtr);
00378     }
00379 
00380     free(bbPtr);
00381 
00382     time(&tempTimeEnd);
00383     IOtime += (tempTimeEnd-tempTimeStart);
00384 }
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 void
00401 Bitio_WriteToSocket(bbPtr, socket)
00402     BitBucket *bbPtr;
00403     int socket;
00404 {
00405     struct bitBucket *ptr, *tempPtr;
00406     uint32 buffer[WORDS_PER_BUCKET];
00407     uint32  lastWord;
00408     int i, nitems;
00409     int     bitsWritten = 0;
00410     int     bitsLeft;
00411     int     numWords;
00412     uint8   charBuf[4];
00413     boolean    flushHere = FALSE;
00414 
00415     bitsLeft = bbPtr->totalbits;
00416 
00417     for (ptr = bbPtr->firstPtr; ptr; ptr = ptr->nextPtr) {
00418         if (ptr->bitsleftcur == 32 && ptr->currword == 0) {
00419             continue;           
00420         }
00421 
00422         if ( bitsLeft >= 32 ) {
00423             if ( ((ptr->currword + 1) * 32) > bitsLeft ) {
00424                 numWords = ptr->currword;
00425                 flushHere = TRUE;
00426             } else {
00427                 numWords = ptr->currword+1;
00428             }
00429 
00430             for (i = 0; i < numWords; i++) {
00431                 buffer[i] = htonl(ptr->bits[i]);
00432             }
00433 
00434             nitems = write(socket, buffer, numWords * sizeof(uint32));
00435             if (nitems != numWords*sizeof(uint32)) {
00436                 fprintf(stderr, "Whoa!  Trouble writing %d bytes (got %d bytes)!  Game over, dude!\n",
00437                         (int)(numWords*sizeof(uint32)), nitems);
00438                 exit(1);
00439             }
00440 
00441             bitsWritten += (numWords * 32);
00442             bitsLeft -= (numWords * 32);
00443         } else {
00444             flushHere = TRUE;
00445         }
00446 
00447         if ( (bitsLeft < 32) && flushHere ) {
00448             lastWord = ptr->bits[ptr->currword];
00449 
00450             
00451 
00452             
00453             while ( bitsLeft > 0 ) {
00454                 charBuf[0] = (lastWord >> 24);
00455                 charBuf[0] &= lower_mask[8];
00456                 if ( write(socket, charBuf, 1) != 1 ) {
00457                     fprintf(stderr, "ERROR:  write of lastPtr bits\n");
00458                     exit(1);
00459                 }
00460                 lastWord = (lastWord << 8);
00461                 bitsLeft -= 8;
00462                 bitsWritten += 8;
00463             }
00464         }
00465     }
00466 
00467     while ( bbPtr->firstPtr != ptr ) {
00468         tempPtr = bbPtr->firstPtr;
00469         bbPtr->firstPtr = tempPtr->nextPtr;
00470         free(tempPtr);
00471     }
00472 
00473     free(bbPtr);
00474 }
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 void
00487 Bitio_BytePad(bbPtr)
00488     BitBucket *bbPtr;
00489 {
00490     struct bitBucket *lastPtrPtr = bbPtr->lastPtr;
00491 
00492     if (lastPtrPtr->bitsleftcur % 8) {
00493         Bitio_Write(bbPtr, 0, lastPtrPtr->bitsleftcur % 8);
00494     }
00495 }
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 static void
00516 Dump(bbPtr)
00517     BitBucket *bbPtr;
00518 {
00519     struct bitBucket *ptr, *tempPtr;
00520     uint32 buffer[WORDS_PER_BUCKET];
00521     int i, nitems;
00522     int     bitsWritten = 0;
00523     time_t  tempTimeStart, tempTimeEnd;
00524 
00525     time(&tempTimeStart);
00526 
00527     for (ptr = bbPtr->firstPtr; ptr && (bitsWritten < MAX_BITS);
00528          ptr = ptr->nextPtr) {
00529         if (ptr->bitsleftcur == 32 && ptr->currword == 0) {
00530             continue;           
00531         }
00532 
00533         for (i = 0; i <= ptr->currword; i++) {
00534             buffer[i] = htonl(ptr->bits[i]);
00535         }
00536 
00537         nitems = fwrite((uint8 *)buffer, sizeof(uint32), (ptr->currword + 1), bbPtr->filePtr);
00538         if (nitems != (ptr->currword+1)) {
00539             fprintf(stderr, "Whoa!  Trouble writing %d bytes (got %d items)!  Game over, dude!\n",
00540                     (int)((ptr->currword+1)), nitems);
00541             assert(0);
00542             exit(1);
00543         }
00544 
00545         bitsWritten += ((ptr->currword + 1) * 32);
00546     }
00547 
00548     while ( bbPtr->firstPtr != ptr ) {
00549         tempPtr = bbPtr->firstPtr;
00550         bbPtr->firstPtr = tempPtr->nextPtr;
00551         free(tempPtr);
00552     }
00553 
00554     bbPtr->totalbits -= bitsWritten;
00555     bbPtr->bitsWritten += bitsWritten;
00556 
00557     time(&tempTimeEnd);
00558     IOtime += (tempTimeEnd-tempTimeStart);
00559 }
00560 
00561