TekFileBZ2ASCII.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Kevin McBride                                   *
00003  *   kevin@planetsaphire.com                                               *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Library General Public License as       *
00007  *   published by the Free Software Foundation; either version 2 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU Library General Public     *
00016  *   License along with this program; if not, write to the                 *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 
00022 #define     LIBTEKLTI_EXPORT  (0)
00023 
00024 #ifndef     _cplusplus
00025 #define     _cplusplus
00026 #endif      /* _cplusplus */
00027 #include "teklti.h"
00028 
00029 #include <errno.h>
00030 
00031 
00032 #ifndef     TEKLTI_USE_BZIP2
00033 #error You can not compile the BZIP2 interfaces unless TEKLTI_USE_BZIP2 is defined.
00034 #endif      /* TEKLTI_USE_BZIP2 */
00035 
00036 
00037 /*
00038   Our private flags.
00039 */
00040 
00041 enum TekFileBZ2ASCII_Mode
00042 {
00043       TekFileBZ2ASCII_Mode_WriteToFile = 0x0001,
00044       TekFileBZ2ASCII_Mode_EndOfStream = 0x0002,
00045       TekFileBZ2ASCII_Mode_UseLessMemory = 0x0004
00046 };
00047 
00048 
00049 MKTEKUUID(UTekFileBZ2ASCII, "6CC3729C-2D12-11DA-887B-000BDBC434D9")
00050 MKTEKDEBUGSTRING(DBTekFileBZ2ASCII, "TekFileBZ2ASCII")
00051 
00052 
00053 
00057 TekFileBZ2ASCII::TekFileBZ2ASCII()
00058 {
00059       TEKSTD_IMPLEMENT_BEGIN_MYSELF
00060       TEKSTD_IMPLEMENT_INTERFACE_MYSELF(UTekFile)
00061       TEKSTD_IMPLEMENT_INTERFACE_MYSELF(UTekFileASCII)
00062       TEKSTD_IMPLEMENT_INTERFACE_MYSELF(UTekFileBZ2)
00063       TEKSTD_IMPLEMENT_INTERFACE_MYSELF(UTekFileBZ2ASCII)
00064       TEKSTD_IMPLEMENT_END_MYSELF
00065 
00066       /* Set everything up. */
00067       this->PrivFileDesc = NULL;
00068       this->PrivBZ2FileDesc = NULL;
00069       this->PrivFlags = 0;
00070       this->PrivBlockSize = TEKLTI_USE_BZIP2_BLOCKSIZE;
00071       this->PrivBytesIn = this->PrivBytesOut = 0;
00072       this->PrivVerbosity = 0;
00073       this->PrivWorkFactor = 30;
00074       this->PrivFilename.uchar_t_ascii =
00075         (char *)calloc(PATH_MAX,sizeof(char));
00076       this->PrivFilename.uchar_t_asciilen = 0;
00077 }
00078 
00082 TekFileBZ2ASCII::~TekFileBZ2ASCII()
00083 {
00084       this->Close();
00085 
00086       if ( this->PrivFilename.uchar_t_ascii != NULL )
00087             free(this->PrivFilename.uchar_t_ascii);
00088 
00089       TEKSTD_IMPLEMENT_FREE
00090 }
00091 
00092 
00093 TEKSTD_SOURCE_FUNC(TekFileBZ2ASCII);
00094 
00095 
00108 TEKERR TekFileBZ2ASCII::ReadLine(uchar_t** Buffer, unsigned long ReadMax)
00109 {
00110       char * buf;
00111       uchar_t * ubuffer;
00112       unsigned long l, in;
00113       TEKERR terr;
00114 
00115 #ifndef     NO_SIZE_T_CHECKS
00116       if ( Buffer == NULL )
00117             return TEKERR_POINTER;
00118 #endif      /* NO_SIZE_T_CHECKS */
00119 
00120 #ifndef     NO_INTERNAL_NULL_CHECKS
00121       if ( this->PrivBZ2FileDesc == NULL )
00122             return TEKERR_SEQUENCE;
00123       if ( this->PrivFileDesc == NULL )
00124             return TEKERR_SEQUENCE;
00125 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00126 
00127 
00128       if ( ReadMax > TEKFILEASCII_STDBUFLEN )
00129             ReadMax = TEKFILEASCII_STDBUFLEN;
00130 
00131       /* Get ready to check the passed-in pointer. */
00132       ubuffer = *Buffer;
00133 
00134       if ( ubuffer == NULL )
00135       {
00136             /* Caller wants us to create a uchar_t. */
00137             ubuffer = (uchar_t *)malloc(sizeof(uchar_t));
00138             /* If malloc() didn't fail, try to allocate the string. */
00139             if ( ubuffer == NULL )
00140             {
00141                   return TEKERR_MEMORY;
00142             } else {
00143                   ubuffer->uchar_t_ascii = (char *)
00144                         calloc(TEKFILEASCII_STDBUFLEN + 1, sizeof(char));
00145                   if ( ubuffer->uchar_t_ascii == NULL )
00146                   {
00147                         /* If calloc() failed, there's nothing to do. */
00148                         free(ubuffer);
00149                         return TEKERR_MEMORY;
00150                   }
00151 
00152                   /* Set up the length value. */
00153                   ubuffer->uchar_t_asciilen =
00154                         (TEKFILEASCII_STDBUFLEN + 1) * sizeof(char);
00155             }
00156 
00157             *Buffer = ubuffer;
00158       }
00159 #ifdef      TEKLTI_ENFORCE_PRIVACY
00160       else
00161       {
00162             /* Clear out the memory. */
00163             memset(
00164                   ubuffer->uchar_t_ascii,
00165                   '\0',
00166                   (TEKFILEASCII_STDBUFLEN + 1) * sizeof(char)
00167             );
00168       }
00169 #endif      /* TEKLTI_ENFORCE_PRIVACY */
00170 
00171       buf = ubuffer->uchar_t_ascii;
00172 
00173       for ( l=0; l < ReadMax; l++ )
00174       {
00175             terr = this->Read(buf, 1, &in);
00176             if ( terr != TEKERR_OK )
00177             {
00178                   if (
00179                   ( terr == TEKERR_FILE_EOF ) &&
00180                   ( in != 0 )
00181                   )
00182                   {
00183                         buf[1] = '\0';
00184                   }
00185                   
00186                   return terr;
00187             }
00188 
00189             /* Detect for carriage return. */
00190             if ( buf[0] == '\r' )
00191             {
00192                   /* Check for a line feed ahead of it. */
00193                   buf++;
00194                   terr = this->Read(buf, 1, &in);
00195                   if ( terr != TEKERR_OK )
00196                   {
00197                         if (
00198                         ( terr == TEKERR_FILE_EOF ) &&
00199                         ( in != 0 )
00200                         )
00201                         {
00202                               buf[0] = '\0';
00203                         }
00204                   
00205                         return terr;
00206                   }
00207 
00208                   /* If yes, cover them with zeroes. */
00209                   if ( buf[0] = '\n' )
00210                   {
00211                         buf--;
00212                         buf[0] = '\0';
00213                         buf[1] = '\0';
00214                         return TEKERR_FILE_EOF;
00215                   }
00216 
00217                   /* If not, continue looking. */
00218                   buf++;
00219                   continue;
00220             } else {
00221 
00222             /* Detect for line feed. */
00223             if ( buf[0] == '\n' )
00224             {
00225                   buf[0] = '\0';
00226                   return TEKERR_FILE_EOF;
00227             }
00228             }
00229 
00230             buf++;
00231       }
00232 
00233       return TEKERR_OK;
00234 }
00235 
00242 TEKERR TekFileBZ2ASCII::WriteLine(const uchar_t* Buffer)
00243 {
00244       unsigned long Wrote;
00245       const char * Buf;
00246       size_t RealLen;
00247       TEKERR terr;
00248 
00249 #ifndef     NO_SIZE_T_CHECKS
00250       if ( Buffer == NULL )
00251             return TEKERR_POINTER;
00252 #endif      /* NO_SIZE_T_CHECKS */
00253 
00254 #ifndef     NO_INTERNAL_NULL_CHECKS
00255       if ( this->PrivBZ2FileDesc == NULL )
00256             return TEKERR_SEQUENCE;
00257       if ( this->PrivFileDesc == NULL )
00258             return TEKERR_SEQUENCE;
00259 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00260 
00261       /* Get ready to look for true EOL. */
00262       Buf = Buffer->uchar_t_ascii;
00263       RealLen = 0;
00264 
00265       /* Look for EOL. */
00266       for ( RealLen=0; RealLen < Buffer->uchar_t_asciilen; RealLen++ )
00267       {
00268             if ( Buf[0] == '\0' )
00269                   break;
00270       }
00271 
00272       /* Write the result to the stream. */
00273       terr = this->Write(Buffer->uchar_t_ascii, RealLen, &Wrote);
00274       if ( terr != TEKERR_OK )
00275             return terr;
00276       if ( Wrote < RealLen )
00277             return TEKERR_FILE_DISKFULL;
00278 
00279       /* Terminate the line. */
00280 #ifdef      TEKLTI_WRITELINE_CRLF
00281       terr = this->Write((void *)"\r\n", 2, &Wrote);
00282       if ( terr != TEKERR_OK )
00283             return terr;
00284       if ( Wrote < 2 )
00285       {
00286 #else /* not TEKLTI_WRITELINE_CRLF */
00287       terr = this->Write((void *)"\n", 1, &Wrote);
00288       if ( terr != TEKERR_OK )
00289             return terr;
00290       if ( Wrote < 1 )
00291       {
00292 #endif      /* not TEKLTI_WRITELINE_CRLF */
00293             return TEKERR_FILE_DISKFULL;
00294       }
00295       return TEKERR_OK;
00296 }
00297 
00298 
00308 TEKERR TekFileBZ2ASCII::get_BytesIn(uint64_t * RetVal)
00309 {
00310 #ifndef     NO_SIZE_T_CHECKS
00311       if ( RetVal == NULL )
00312             return TEKERR_POINTER;
00313 #endif      /* NO_SIZE_T_CHECKS */
00314 
00315       *RetVal = this->PrivBytesIn;
00316 
00317       return TEKERR_OK;
00318 }
00319 
00320 
00331 TEKERR TekFileBZ2ASCII::get_BytesOut(uint64_t * RetVal)
00332 {
00333 #ifndef     NO_SIZE_T_CHECKS
00334       if ( RetVal == NULL )
00335             return TEKERR_POINTER;
00336 #endif      /* NO_SIZE_T_CHECKS */
00337 
00338       *RetVal = this->PrivBytesOut;
00339 
00340       return TEKERR_OK;
00341 }
00342 
00343 
00354 TEKERR TekFileBZ2ASCII::put_UseLessMemory(unsigned int NewVal)
00355 {
00356 #ifndef     NO_INTERNAL_NULL_CHECKS
00357       if ( this->PrivBZ2FileDesc != NULL )
00358             return TEKERR_ACCESS;
00359 #endif      /* NO_INTERNAL_NULL_CHECKS */
00360 
00361       if ( NewVal == 0 )
00362       {
00363             /* Reset the UseLessMemory flag. */
00364             if ( this->PrivFlags & TekFileBZ2ASCII_Mode_UseLessMemory )
00365                   this->PrivFlags ^= TekFileBZ2ASCII_Mode_UseLessMemory;
00366       } else {
00367             /* Set the UseLessMemory flag. */
00368             this->PrivFlags |= TekFileBZ2ASCII_Mode_UseLessMemory;
00369       }
00370 
00371       return TEKERR_OK;
00372 }
00373 
00374 
00381 TEKERR TekFileBZ2ASCII::get_UseLessMemory(unsigned int * RetVal)
00382 {
00383 #ifndef     NO_SIZE_T_CHECKS
00384       if ( RetVal == NULL )
00385             return TEKERR_POINTER;
00386 #endif      /* NO_SIZE_T_CHECKS */
00387 
00388       if ( this->PrivFlags & TekFileBZ2ASCII_Mode_UseLessMemory )
00389             *RetVal = 1;
00390       else
00391             *RetVal = 0;
00392 
00393       return TEKERR_OK;
00394 }
00395 
00396 
00410 TEKERR TekFileBZ2ASCII::put_WorkFactor(unsigned int NewVal)
00411 {
00412 #ifndef     NO_INTERNAL_NULL_CHECKS
00413       if ( this->PrivBZ2FileDesc != NULL )
00414             return TEKERR_ACCESS;
00415 #endif      /* NO_INTERNAL_NULL_CHECKS */
00416 
00417       this->PrivWorkFactor = NewVal;
00418 
00419       return TEKERR_OK;
00420 }
00421 
00422 
00429 TEKERR TekFileBZ2ASCII::get_WorkFactor(unsigned int * RetVal)
00430 {
00431 #ifndef     NO_SIZE_T_CHECKS
00432       if ( RetVal == NULL )
00433             return TEKERR_POINTER;
00434 #endif      /* NO_SIZE_T_CHECKS */
00435 
00436       *RetVal = (unsigned int)this->PrivWorkFactor;
00437 
00438       return TEKERR_OK;
00439 }
00440 
00441 
00452 TEKERR TekFileBZ2ASCII::put_Verbosity(unsigned int NewVal)
00453 {
00454 #ifndef     NO_INTERNAL_NULL_CHECKS
00455       if ( this->PrivBZ2FileDesc != NULL )
00456             return TEKERR_ACCESS;
00457 #endif      /* NO_INTERNAL_NULL_CHECKS */
00458 
00459       this->PrivVerbosity = (int)NewVal;
00460 
00461       return TEKERR_OK;
00462 }
00463 
00464 
00471 TEKERR TekFileBZ2ASCII::get_Verbosity(unsigned int * RetVal)
00472 {
00473 #ifndef     NO_SIZE_T_CHECKS
00474       if ( RetVal == NULL )
00475             return TEKERR_POINTER;
00476 #endif      /* NO_SIZE_T_CHECKS */
00477 
00478       *RetVal = (unsigned int)this->PrivVerbosity;
00479 
00480       return TEKERR_OK;
00481 }
00482 
00483 
00494 TEKERR TekFileBZ2ASCII::put_BlockSize(unsigned int NewVal)
00495 {
00496 #ifndef     NO_INTERNAL_NULL_CHECKS
00497       if ( this->PrivBZ2FileDesc != NULL )
00498             return TEKERR_ACCESS;
00499 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00500 
00501       if ( ( NewVal < 1 ) || ( NewVal > 9 ) )
00502             return TEKERR_FAIL;
00503 
00504       this->PrivBlockSize = NewVal;
00505 
00506       return TEKERR_OK;
00507 }
00508 
00509 
00515 TEKERR TekFileBZ2ASCII::get_BlockSize(unsigned int * RetVal)
00516 {
00517 #ifndef     NO_SIZE_T_CHECKS
00518       if ( RetVal == NULL )
00519             return TEKERR_POINTER;
00520 #endif      /* NO_SIZE_T_CHECKS */
00521 
00522       *RetVal = this->PrivBlockSize;
00523 
00524       return TEKERR_OK;
00525 }
00526 
00527 
00538 TEKERR TekFileBZ2ASCII::CloseStream()
00539 {
00540       struct i64 bzIn, bzOut;
00541       int bzError;
00542 
00543 #ifndef NO_INTERNAL_NULL_CHECKS
00544         if ( this->PrivBZ2FileDesc == NULL )
00545                 return TEKERR_SEQUENCE;
00546 #endif  /* NO_INTERNAL_NULL_CHECKS */
00547 
00548       /* Reset the EndOfStream flag. */
00549       if ( this->PrivFlags & TekFileBZ2ASCII_Mode_EndOfStream )
00550             this->PrivFlags ^= TekFileBZ2ASCII_Mode_EndOfStream;
00551 
00552       /* Determine if there is a BZ2 Descriptor open. */
00553       if ( this->PrivBZ2FileDesc != NULL )
00554       {
00555             /* How should we close the stream? */
00556             if ( this->PrivFlags & TekFileBZ2ASCII_Mode_WriteToFile )
00557             {
00558                   /* Do a write close. */
00559                   BZ2_bzWriteClose64(
00560                         &bzError,
00561                         this->PrivBZ2FileDesc,
00562                         0,
00563                         &bzIn.i64_a,
00564                         &bzIn.i64_b,
00565                         &bzOut.i64_a,
00566                         &bzOut.i64_b
00567                   );
00568                   /* Convert our data into uint64_t's. */
00569                   memcpy(&this->PrivBytesIn, &bzIn, 8);
00570                   memcpy(&this->PrivBytesOut, &bzOut, 8);
00571 
00572                   /* Handle the error, if necessary. */
00573                   if ( bzError == BZ_IO_ERROR )
00574                         return TEKERR_FILE_IO;
00575             } else {
00576                   /* Do a read close. */
00577                   BZ2_bzReadClose(
00578                         &bzError,
00579                         this->PrivBZ2FileDesc
00580                   );
00581             }
00582 
00583             /* Handle any catastrophic errors. */
00584             if ( bzError != BZ_OK )
00585                   return TEKERR_UNEXPECTED;
00586 
00587             /* NULLify the stream descriptor. */
00588             this->PrivBZ2FileDesc = NULL;
00589       }
00590 
00591       /* Return to caller. */
00592       return TEKERR_OK;
00593 }
00594 
00595 
00602 TEKERR TekFileBZ2ASCII::OpenStream()
00603 {
00604       BZFILE * NewStream;
00605       int bzError;
00606       int UseSmallMemory;
00607 
00608 #ifndef     NO_INTERNAL_NULL_CHECKS
00609       if ( this->PrivFileDesc == NULL )
00610             return TEKERR_SEQUENCE;
00611       if ( this->PrivBZ2FileDesc != NULL )
00612             return TEKERR_SEQUENCE;
00613 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00614 
00615       /* How should we open the stream? */
00616       if ( this->PrivFlags & TekFileBZ2ASCII_Mode_WriteToFile )
00617       {
00618             //* Open a stream. */
00619             NewStream = BZ2_bzWriteOpen(
00620                   &bzError,
00621                   this->PrivFileDesc,
00622                   this->PrivBlockSize,
00623                   this->PrivVerbosity,
00624                   this->PrivWorkFactor
00625             );
00626       } else {
00627             /* Determine if SmallMemory is to be used. */
00628             if ( this->PrivFlags & TekFileBZ2ASCII_Mode_UseLessMemory )
00629                   UseSmallMemory = 1;
00630             else
00631                   UseSmallMemory = 0;
00632 
00633             /* Open a stream. */
00634             NewStream = BZ2_bzReadOpen(
00635                   &bzError,
00636                   this->PrivFileDesc,
00637                   this->PrivVerbosity,
00638                   UseSmallMemory,
00639                   NULL,
00640                   0
00641             );
00642       }
00643 
00644       return TEKERR_OK;
00645 }
00646 
00647 
00656 TEKERR TekFileBZ2ASCII::get_FILE(FILE ** FileDescriptor)
00657 {
00658 #ifndef     NO_INTERNAL_NULL_CHECKS
00659       if ( this->PrivBZ2FileDesc != NULL )
00660             return TEKERR_ACCESS;
00661 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00662 
00663 #ifndef     NO_SIZE_T_CHECKS
00664       if ( FileDescriptor == (FILE **)NULL )
00665             return TEKERR_POINTER;
00666 #endif      /* not NO_SIZE_T_CHECKS */
00667 
00668       *FileDescriptor = this->PrivFileDesc;
00669 
00670       return TEKERR_OK;
00671 }
00672 
00673 
00682 TEKERR TekFileBZ2ASCII::get_Filename(uchar_t ** Name)
00683 {
00684       uchar_t * RetVal;
00685 
00686 #ifndef     NO_SIZE_T_CHECKS
00687       if ( Name == (uchar_t **)NULL )
00688             return TEKERR_POINTER;
00689 #endif      /* not NO_SIZE_T_CHECKS */
00690 
00691       /* Check to see if the constructor was able to allocate memory. */
00692       if ( this->PrivFilename.uchar_t_ascii == NULL )
00693             return TEKERR_MEMORY;
00694 
00695       if ( this->PrivFilename.uchar_t_ascii[0] == '\0' )
00696             return TEKERR_ACCESS;
00697 
00698       RetVal = char2uchar(this->PrivFilename.uchar_t_ascii);
00699       if ( RetVal == NULL )
00700             return TEKERR_MEMORY;
00701 
00702       *Name = RetVal;
00703 
00704       return TEKERR_OK;
00705 }
00706 
00707 
00723 TEKERR TekFileBZ2ASCII::put_FILE(FILE * FileDescriptor)
00724 {
00725 #ifndef     NO_INTERNAL_NULL_CHECKS
00726       if ( this->PrivBZ2FileDesc != NULL )
00727             return TEKERR_ACCESS;
00728       if ( ( this->PrivFileDesc != NULL ) && ( FileDescriptor != NULL ) )
00729             return TEKERR_ACCESS;
00730 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00731 
00732       if ( ( FileDescriptor == NULL ) && ( this->PrivFileDesc != NULL ) )
00733       {
00734             if ( this->PrivBZ2FileDesc != NULL )
00735                   this->CloseStream();
00736             this->Close();
00737       }
00738 
00739       this->PrivFileDesc = FileDescriptor;
00740 
00741       return TEKERR_OK;
00742 }
00743 
00744 
00753 TEKERR TekFileBZ2ASCII::put_Filename(uchar_t * Name)
00754 {
00755 #ifndef     NO_INTERNAL_NULL_CHECKS
00756       if ( this->PrivFileDesc != NULL )
00757             return TEKERR_ACCESS;
00758 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00759 
00760 #ifndef     NO_SIZE_T_CHECKS
00761       if ( Name == NULL )
00762             return TEKERR_POINTER;
00763 #endif      /* not NO_SIZE_T_CHECKS */
00764 
00765       /* Determine the length. */
00766       this->PrivFilename.uchar_t_asciilen =
00767         strlen(Name->uchar_t_ascii);
00768 
00769       /* Check to see if the constructor was able to allocate memory. */
00770       if ( this->PrivFilename.uchar_t_ascii == NULL )
00771             return TEKERR_MEMORY;
00772 
00773       /* Copy the Filename string. */
00774       strcpy(this->PrivFilename.uchar_t_ascii, Name->uchar_t_ascii);
00775 
00776       return TEKERR_OK;
00777 }
00778 
00779 
00785 TEKERR TekFileBZ2ASCII::get_Type(TekFileType * FileTypePointer)
00786 {
00787 #ifndef     NO_SIZE_T_CHECKS
00788       if ( FileTypePointer == NULL )
00789             return TEKERR_POINTER;
00790 #endif      /* NO_SIZE_T_CHECKS */
00791 
00792       *FileTypePointer = TekFileType_BZIP2_ASCII;
00793 
00794       return TEKERR_OK;
00795 }
00796 
00797 
00803 TEKERR TekFileBZ2ASCII::Close()
00804 {
00805       struct i64 bzIn, bzOut;
00806       int bzError;
00807 
00808       /* Determine if there is a BZ2 Descriptor open. */
00809       if ( this->PrivBZ2FileDesc != NULL )
00810       {
00811             /* How should we close the stream? */
00812             if ( this->PrivFlags & TekFileBZ2ASCII_Mode_WriteToFile )
00813             {
00814                   /* Do a write close. */
00815                   BZ2_bzWriteClose64(
00816                         &bzError,
00817                         this->PrivBZ2FileDesc,
00818                         0,
00819                         &bzIn.i64_a,
00820                         &bzIn.i64_b,
00821                         &bzOut.i64_a,
00822                         &bzOut.i64_b
00823                   );
00824                   /* Convert our data into uint64_t's. */
00825                   memcpy(&this->PrivBytesIn, &bzIn, 8);
00826                   memcpy(&this->PrivBytesOut, &bzOut, 8);
00827 
00828                   /* Handle the error, if necessary. */
00829                   if ( bzError == BZ_IO_ERROR )
00830                         return TEKERR_FILE_IO;
00831             } else {
00832                   /* Do a read close. */
00833                   BZ2_bzReadClose(
00834                         &bzError,
00835                         this->PrivBZ2FileDesc
00836                   );
00837             }
00838 
00839             /* Handle any catastrophic errors. */
00840             if ( bzError != BZ_OK )
00841                   return TEKERR_UNEXPECTED;
00842 
00843             /* NULLify the stream descriptor. */
00844             this->PrivBZ2FileDesc = NULL;
00845 
00846             if ( (this->PrivFlags & TekFileBZ2ASCII_Mode_EndOfStream) != 0 )
00847                   this->PrivFlags ^= TekFileBZ2ASCII_Mode_EndOfStream;
00848       }
00849 
00850       /* Determine if there is a FILE descriptor open. */
00851       if ( this->PrivFileDesc != NULL )
00852       {
00853             /* Close the descriptor. */
00854             if ( fclose(this->PrivFileDesc) != 0 )
00855             {
00856                   /* Handle the error. */
00857                   if ( errno == ENOSPC )
00858                         return TEKERR_FILE_DISKFULL;
00859                   else
00860                         return TEKERR_FILE_IO;
00861             }
00862 
00863             /* NULLify the FILE descriptor. */
00864             this->PrivFileDesc = NULL;
00865       }
00866 
00867       /* We're all done here. */
00868       return TEKERR_OK;
00869 }
00870 
00871 
00877 TEKERR TekFileBZ2ASCII::get_Mode(TekFileMode * ModeID)
00878 {
00879 #ifndef     NO_SIZE_T_CHECKS
00880       if ( ModeID == NULL )
00881             return TEKERR_POINTER;
00882 #endif      /* NO_SIZE_T_CHECKS */
00883 
00884       /* Determine if the WriteToFile bit is set. */
00885       if ( this->PrivFlags && TekFileBZ2ASCII_Mode_WriteToFile )
00886             *ModeID = TekFileMode_WriteOnly;
00887       else
00888             *ModeID = TekFileMode_ReadOnly;
00889 
00890       /* Return to caller. */
00891       return TEKERR_OK;
00892 }
00893 
00894 
00902 TEKERR TekFileBZ2ASCII::put_Mode(TekFileMode ModeID)
00903 {
00904 #ifndef     NO_INTERNAL_NULL_CHECKS
00905       if ( this->PrivFileDesc != NULL )
00906             return TEKERR_ACCESS;
00907 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00908 
00909       /* Determine whether the flag needs to be set. */
00910       if ( ModeID != TekFileMode_ReadOnly )
00911       {
00912             this->PrivFlags |= TekFileBZ2ASCII_Mode_WriteToFile;
00913       }
00914       else
00915       {
00916             if ( this->PrivFlags && TekFileBZ2ASCII_Mode_WriteToFile )
00917                   this->PrivFlags ^= TekFileBZ2ASCII_Mode_WriteToFile;
00918       }
00919 
00920       /* Return to caller. */
00921       return TEKERR_OK;
00922 }
00923 
00924 
00930 TEKERR TekFileBZ2ASCII::Flush()
00931 {
00932       return TEKERR_NOTIMPL;
00933 }
00934 
00935 
00941 TEKERR TekFileBZ2ASCII::Open()
00942 {
00943       BZFILE * NewStream;
00944       FILE * NewDesc;
00945       int bzError;
00946       int UseSmallMemory;
00947 
00948       /* Make sure the internal buffer isn't NULL. */
00949       if ( this->PrivFilename.uchar_t_ascii == NULL )
00950             return TEKERR_MEMORY;
00951 
00952       /* How should we open the stream? */
00953       if ( this->PrivFlags && TekFileBZ2ASCII_Mode_WriteToFile )
00954       {
00955             /* Open the file for writing. */
00956             NewDesc = fopen(
00957                   this->PrivFilename.uchar_t_ascii,
00958                   "wb"
00959             );
00960             if ( NewDesc == NULL )
00961                   return TEKERR_FILE_IO;
00962 
00963             /* Open a stream. */
00964             NewStream = BZ2_bzWriteOpen(
00965                   &bzError,
00966                   NewDesc,
00967                   this->PrivBlockSize,
00968                   this->PrivVerbosity,
00969                   this->PrivWorkFactor
00970             );
00971       } else {
00972             /* Open the file for reading. */
00973             NewDesc = fopen(
00974                   this->PrivFilename.uchar_t_ascii,
00975                   "rb"
00976             );
00977             if ( NewDesc == NULL )
00978                   return TEKERR_FILE_IO;
00979 
00980             if ( this->PrivFlags & TekFileBZ2ASCII_Mode_UseLessMemory )
00981                   UseSmallMemory = 1;
00982             else
00983                   UseSmallMemory = 0;
00984 
00985             /* Open a stream. */
00986             NewStream = BZ2_bzReadOpen(
00987                   &bzError,
00988                   NewDesc,
00989                   this->PrivVerbosity,
00990                   UseSmallMemory,
00991                   NULL,
00992                   0
00993             );
00994       }
00995 
00996       /* Handle errors. */
00997       if ( bzError != BZ_OK )
00998       {
00999             fclose(NewDesc);
01000             switch ( bzError )
01001             {
01002                   case BZ_IO_ERROR:
01003                         return TEKERR_FILE_IO;
01004                   case BZ_MEM_ERROR:
01005                         return TEKERR_MEMORY;
01006                   case BZ_CONFIG_ERROR:
01007                   case BZ_PARAM_ERROR:
01008                   default:
01009                         return TEKERR_UNEXPECTED;
01010             }
01011       }
01012 
01013       /* Set up our internal pointers. */
01014       this->PrivFileDesc = NewDesc;
01015       this->PrivBZ2FileDesc = NewStream;
01016 
01017       /* Return to caller. */
01018       return TEKERR_OK;
01019 }
01020 
01021 
01027 TEKERR TekFileBZ2ASCII::Open64()
01028 {
01029       BZFILE * NewStream;
01030       FILE * NewDesc;
01031       int bzError;
01032       int UseSmallMemory;
01033 
01034       /* Make sure the internal buffer isn't NULL. */
01035       if ( this->PrivFilename.uchar_t_ascii == NULL )
01036             return TEKERR_MEMORY;
01037 
01038       /* How should we open the stream? */
01039       if ( this->PrivFlags && TekFileBZ2ASCII_Mode_WriteToFile )
01040       {
01041             /* Open the file for writing. */
01042             NewDesc = fopen64(
01043                   this->PrivFilename.uchar_t_ascii,
01044                   "wb"
01045             );
01046             if ( NewDesc == NULL )
01047                   return TEKERR_FILE_IO;
01048 
01049             /* Open a stream. */
01050             NewStream = BZ2_bzWriteOpen(
01051                   &bzError,
01052                   NewDesc,
01053                   this->PrivBlockSize,
01054                   this->PrivVerbosity,
01055                   this->PrivWorkFactor
01056             );
01057       } else {
01058             /* Open the file for reading. */
01059             NewDesc = fopen64(
01060                   this->PrivFilename.uchar_t_ascii,
01061                   "rb"
01062             );
01063             if ( NewDesc == NULL )
01064                   return TEKERR_FILE_IO;
01065 
01066             if ( this->PrivFlags & TekFileBZ2ASCII_Mode_UseLessMemory )
01067                   UseSmallMemory = 1;
01068             else
01069                   UseSmallMemory = 0;
01070 
01071             /* Open a stream. */
01072             NewStream = BZ2_bzReadOpen(
01073                   &bzError,
01074                   NewDesc,
01075                   this->PrivVerbosity,
01076                   UseSmallMemory,
01077                   NULL,
01078                   0
01079             );
01080       }
01081 
01082       /* Handle errors. */
01083       if ( bzError != BZ_OK )
01084       {
01085             fclose(NewDesc);
01086             switch ( bzError )
01087             {
01088                   case BZ_IO_ERROR:
01089                         return TEKERR_FILE_IO;
01090                   case BZ_MEM_ERROR:
01091                         return TEKERR_MEMORY;
01092                   case BZ_CONFIG_ERROR:
01093                   case BZ_PARAM_ERROR:
01094                   default:
01095                         return TEKERR_UNEXPECTED;
01096             }
01097       }
01098 
01099       /* Set up our internal pointers. */
01100       this->PrivFileDesc = NewDesc;
01101       this->PrivBZ2FileDesc = NewStream;
01102 
01103       /* Return to caller. */
01104       return TEKERR_OK;
01105 }
01106 
01107 
01113 TEKERR TekFileBZ2ASCII::Read64(void * Buffer, uint64_t BytesToRead, uint64_t * BytesRead)
01114 {
01115       return TEKERR_NOTIMPL;
01116 }
01117 
01118 
01124 TEKERR TekFileBZ2ASCII::Read(void * Buffer, unsigned long BytesToRead, unsigned long * BytesRead)
01125 {
01126       unsigned long BytesWeRead;
01127       int bzError;
01128 
01129 #ifndef     NO_SIZE_T_CHECKS
01130       if ( Buffer == NULL )
01131             return TEKERR_POINTER;
01132 #endif      /* NO_SIZE_T_CHECKS */
01133 
01134       /* Determine if we ended up with a buffer situation. */
01135       if ( this->PrivFlags & TekFileBZ2ASCII_Mode_EndOfStream )
01136       {
01137             /* Determine if we are at the end. */
01138             if ( BytesToRead >= (unsigned long)this->PrivUnusedLen )
01139             {
01140                   memcpy(Buffer, this->PrivUnused, this->PrivUnusedLen);
01141                   if ( BytesRead != NULL )
01142                         *BytesRead = this->PrivUnusedLen;
01143                   return TEKERR_FILE_EOF;
01144             } else {
01145                   memcpy(Buffer, this->PrivUnused, BytesToRead);
01146                   this->PrivUnused += BytesToRead;
01147                   this->PrivUnusedLen -= BytesToRead;
01148 
01149                   if ( BytesRead != NULL )
01150                         *BytesRead = this->PrivUnusedLen;
01151             }
01152       } else {
01153             /* Read next area in the stream. */
01154             BytesWeRead = (unsigned long)BZ2_bzRead(
01155                   &bzError,
01156                   this->PrivBZ2FileDesc,
01157                   Buffer,
01158                   BytesToRead
01159             );
01160             if ( BytesRead != NULL )
01161                   *BytesRead = BytesWeRead;
01162 
01163             /* Handle errors. */
01164             if ( bzError != BZ_OK )
01165             {
01166                   switch ( bzError )
01167                   {
01168                   case BZ_STREAM_END:
01169                         /* If we're here, we reached end of stream. */
01170                         this->PrivFlags |= TekFileBZ2ASCII_Mode_EndOfStream;
01171                         BZ2_bzReadGetUnused(
01172                               &bzError,
01173                               this->PrivBZ2FileDesc,
01174                               (void**)&this->PrivUnused,
01175                               &this->PrivUnusedLen
01176                         );
01177                         if ( bzError != BZ_OK )
01178                               return TEKERR_UNEXPECTED;
01179                         if ( this->PrivUnusedLen == 0 )
01180                               return TEKERR_FILE_EOF;
01181                         break;
01182                   case BZ_MEM_ERROR:
01183                         return TEKERR_MEMORY;
01184                   case BZ_IO_ERROR:
01185                         return TEKERR_FILE_IO;
01186                   case BZ_DATA_ERROR:
01187                   case BZ_DATA_ERROR_MAGIC:
01188                   case BZ_UNEXPECTED_EOF:
01189                   case BZ_SEQUENCE_ERROR:
01190                   case BZ_PARAM_ERROR:
01191                   default:
01192                         return TEKERR_UNEXPECTED;
01193                   }
01194             }
01195       }
01196 
01197       /* Return to caller. */
01198       return TEKERR_OK;
01199 }
01200 
01201 
01207 TEKERR TekFileBZ2ASCII::Seek64(TekFileSeek SeekWhere, int64_t NewLocation)
01208 {
01209       return TEKERR_NOTIMPL;
01210 }
01211 
01212 
01218 TEKERR TekFileBZ2ASCII::Seek(TekFileSeek SeekWhere, signed long NewLocation)
01219 {
01220       return TEKERR_NOTIMPL;
01221 }
01222 
01223 
01229 TEKERR TekFileBZ2ASCII::Write64(void * Buffer, uint64_t BytesToWrite, uint64_t * BytesWrote)
01230 {
01231       return TEKERR_NOTIMPL;
01232 }
01233 
01234 
01240 TEKERR TekFileBZ2ASCII::Write(void * Buffer, unsigned long BytesToWrite, unsigned long * BytesWrote)
01241 {
01242       int bzError;
01243 
01244 #ifndef     NO_SIZE_T_CHECKS
01245       if ( Buffer == NULL )
01246             return TEKERR_POINTER;
01247 #endif      /* NO_SIZE_T_CHECKS */
01248 
01249       /* Write out the buffer. */
01250       BZ2_bzWrite(&bzError, this->PrivBZ2FileDesc, Buffer, BytesToWrite);
01251       /* Handle any errors. */
01252       if ( bzError != BZ_OK )
01253       {
01254             switch ( bzError )
01255             {
01256                   case BZ_SEQUENCE_ERROR:
01257                         return TEKERR_SEQUENCE;
01258                   case BZ_IO_ERROR:
01259                         if ( errno == ENOSPC )
01260                               return TEKERR_FILE_DISKFULL;
01261                         return TEKERR_FILE_IO;
01262                   case BZ_PARAM_ERROR:
01263                   default:
01264                         return TEKERR_UNEXPECTED;
01265             }
01266       }
01267 
01268       /* Set *BytesWrote. */
01269       if ( BytesWrote != NULL )
01270             *BytesWrote = BytesToWrite;
01271 
01272       /* Return to caller. */
01273       return TEKERR_OK;
01274 }
01275 
01276 
01287 TEKERR TekFileBZ2ASCII::get_Location(unsigned long * Location)
01288 {
01289       return TEKERR_NOTIMPL;
01290 }
01291 
01292 
01303 TEKERR TekFileBZ2ASCII::get_Location64(uint64_t * Location)
01304 {
01305       return TEKERR_NOTIMPL;
01306 }
01307 
01308 
SourceForge.net Logo  Technical Library Template Interface Project Page