TekFileBZ2Binary.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 
00030 #include <errno.h>
00031 
00032 
00033 #ifndef     TEKLTI_USE_BZIP2
00034 #error You can not compile the BZIP2 interfaces unless TEKLTI_USE_BZIP2 is defined.
00035 #endif      /* TEKLTI_USE_BZIP2 */
00036 
00037 
00038 /*
00039   Our private flags.
00040 */
00041 
00042 enum TekFileBZ2Binary_Mode
00043 {
00044       TekFileBZ2Binary_Mode_WriteToFile = 0x0001,
00045       TekFileBZ2Binary_Mode_EndOfStream = 0x0002,
00046       TekFileBZ2Binary_Mode_UseLessMemory = 0x0004
00047 };
00048 
00049 
00050 MKTEKUUID(UTekFileBZ2Binary, "6E9A6C06-2D12-11DA-99DC-000BDBC434D9")
00051 MKTEKDEBUGSTRING(DBTekFileBZ2Binary, "TekFileBZ2Binary")
00052 
00053 
00057 TekFileBZ2Binary::TekFileBZ2Binary()
00058 {
00059       TEKSTD_IMPLEMENT_INTERFACE(UTekFile)
00060       TEKSTD_IMPLEMENT_INTERFACE(UTekFileBZ2)
00061       TEKSTD_IMPLEMENT_INTERFACE(UTekFileBZ2Binary)
00062       TEKSTD_IMPLEMENT_ENDBASE
00063 
00064       /* Set everything up. */
00065       this->PrivFileDesc = NULL;
00066       this->PrivBZ2FileDesc = NULL;
00067       this->PrivFlags = 0;
00068       this->PrivBlockSize = TEKLTI_USE_BZIP2_BLOCKSIZE;
00069       this->PrivBytesIn = this->PrivBytesOut = 0;
00070       this->PrivWorkFactor = 30;
00071       this->PrivVerbosity = 0;
00072       this->PrivFilename.uchar_t_ascii =
00073         (char *)calloc(PATH_MAX,sizeof(char));
00074       this->PrivFilename.uchar_t_asciilen = 0;
00075 }
00076 
00077 
00081 TekFileBZ2Binary::~TekFileBZ2Binary()
00082 {
00083       if ( this->PrivFilename.uchar_t_ascii != NULL )
00084             free(this->PrivFilename.uchar_t_ascii);
00085 
00086       this->Close();
00087 }
00088 
00089 
00090 //TEKSTD_SOURCE_FUNC(TekFileBZ2Binary)
00091 
00092 
00102 TEKERR TekFileBZ2Binary::get_BytesIn(uint64_t * RetVal)
00103 {
00104 #ifndef     NO_SIZE_T_CHECKS
00105       if ( RetVal == NULL )
00106             return TEKERR_POINTER;
00107 #endif      /* NO_SIZE_T_CHECKS */
00108 
00109       *RetVal = this->PrivBytesIn;
00110 
00111       return TEKERR_OK;
00112 }
00113 
00114 
00125 TEKERR TekFileBZ2Binary::get_BytesOut(uint64_t * RetVal)
00126 {
00127 #ifndef     NO_SIZE_T_CHECKS
00128       if ( RetVal == NULL )
00129             return TEKERR_POINTER;
00130 #endif      /* NO_SIZE_T_CHECKS */
00131 
00132       *RetVal = this->PrivBytesOut;
00133 
00134       return TEKERR_OK;
00135 }
00136 
00137 
00148 TEKERR TekFileBZ2Binary::put_UseLessMemory(unsigned int NewVal)
00149 {
00150 #ifndef     NO_INTERNAL_NULL_CHECKS
00151       if ( this->PrivBZ2FileDesc != NULL )
00152             return TEKERR_ACCESS;
00153 #endif      /* NO_INTERNAL_NULL_CHECKS */
00154 
00155       if ( NewVal == 0 )
00156       {
00157             /* Reset the UseLessMemory flag. */
00158             if ( this->PrivFlags & TekFileBZ2Binary_Mode_UseLessMemory )
00159                   this->PrivFlags ^= TekFileBZ2Binary_Mode_UseLessMemory;
00160       } else {
00161             /* Set the UseLessMemory flag. */
00162             this->PrivFlags |= TekFileBZ2Binary_Mode_UseLessMemory;
00163       }
00164 
00165       return TEKERR_OK;
00166 }
00167 
00168 
00175 TEKERR TekFileBZ2Binary::get_UseLessMemory(unsigned int * RetVal)
00176 {
00177 #ifndef     NO_SIZE_T_CHECKS
00178       if ( RetVal == NULL )
00179             return TEKERR_POINTER;
00180 #endif      /* NO_SIZE_T_CHECKS */
00181 
00182       if ( this->PrivFlags & TekFileBZ2Binary_Mode_UseLessMemory )
00183             *RetVal = 1;
00184       else
00185             *RetVal = 0;
00186 
00187       return TEKERR_OK;
00188 }
00189 
00190 
00204 TEKERR TekFileBZ2Binary::put_WorkFactor(unsigned int NewVal)
00205 {
00206 #ifndef     NO_INTERNAL_NULL_CHECKS
00207       if ( this->PrivBZ2FileDesc != NULL )
00208             return TEKERR_ACCESS;
00209 #endif      /* NO_INTERNAL_NULL_CHECKS */
00210 
00211       this->PrivWorkFactor = NewVal;
00212 
00213       return TEKERR_OK;
00214 }
00215 
00216 
00223 TEKERR TekFileBZ2Binary::get_WorkFactor(unsigned int * RetVal)
00224 {
00225 #ifndef     NO_SIZE_T_CHECKS
00226       if ( RetVal == NULL )
00227             return TEKERR_POINTER;
00228 #endif      /* NO_SIZE_T_CHECKS */
00229 
00230       *RetVal = (unsigned int)this->PrivWorkFactor;
00231 
00232       return TEKERR_OK;
00233 }
00234 
00235 
00246 TEKERR TekFileBZ2Binary::put_Verbosity(unsigned int NewVal)
00247 {
00248 #ifndef     NO_INTERNAL_NULL_CHECKS
00249       if ( this->PrivBZ2FileDesc != NULL )
00250             return TEKERR_ACCESS;
00251 #endif      /* NO_INTERNAL_NULL_CHECKS */
00252 
00253       this->PrivVerbosity = (int)NewVal;
00254 
00255       return TEKERR_OK;
00256 }
00257 
00258 
00265 TEKERR TekFileBZ2Binary::get_Verbosity(unsigned int * RetVal)
00266 {
00267 #ifndef     NO_SIZE_T_CHECKS
00268       if ( RetVal == NULL )
00269             return TEKERR_POINTER;
00270 #endif      /* NO_SIZE_T_CHECKS */
00271 
00272       *RetVal = (unsigned int)this->PrivVerbosity;
00273 
00274       return TEKERR_OK;
00275 }
00276 
00277 
00288 TEKERR TekFileBZ2Binary::put_BlockSize(unsigned int NewVal)
00289 {
00290 #ifndef     NO_INTERNAL_NULL_CHECKS
00291       if ( this->PrivBZ2FileDesc != NULL )
00292             return TEKERR_ACCESS;
00293 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00294 
00295       if ( ( NewVal < 1 ) || ( NewVal > 9 ) )
00296             return TEKERR_FAIL;
00297 
00298       this->PrivBlockSize = NewVal;
00299 
00300       return TEKERR_OK;
00301 }
00302 
00303 
00309 TEKERR TekFileBZ2Binary::get_BlockSize(unsigned int * RetVal)
00310 {
00311 #ifndef     NO_SIZE_T_CHECKS
00312       if ( RetVal == NULL )
00313             return TEKERR_POINTER;
00314 #endif      /* NO_SIZE_T_CHECKS */
00315 
00316       *RetVal = this->PrivBlockSize;
00317 
00318       return TEKERR_OK;
00319 }
00320 
00321 
00332 TEKERR TekFileBZ2Binary::CloseStream()
00333 {
00334       struct i64 bzIn, bzOut;
00335       int bzError;
00336 
00337 #ifndef     NO_INTERNAL_NULL_CHECKS
00338       if ( this->PrivBZ2FileDesc == NULL )
00339             return TEKERR_SEQUENCE;
00340 #endif      /* NO_INTERNAL_NULL_CHECKS */
00341 
00342       if ( this->PrivFlags & TekFileBZ2Binary_Mode_EndOfStream )
00343             this->PrivFlags ^= TekFileBZ2Binary_Mode_EndOfStream;
00344 
00345       /* Determine if there is a BZ2 Descriptor open. */
00346       if ( this->PrivBZ2FileDesc != NULL )
00347       {
00348             /* How should we close the stream? */
00349             if ( this->PrivFlags & TekFileBZ2Binary_Mode_WriteToFile )
00350             {
00351                   /* Do a write close. */
00352                   BZ2_bzWriteClose64(
00353                         &bzError,
00354                         this->PrivBZ2FileDesc,
00355                         0,
00356                         &bzIn.i64_a,
00357                         &bzIn.i64_b,
00358                         &bzOut.i64_a,
00359                         &bzOut.i64_b
00360                   );
00361                   /* Convert our data into uint64_t's. */
00362                   memcpy(&this->PrivBytesIn, &bzIn, 8);
00363                   memcpy(&this->PrivBytesOut, &bzOut, 8);
00364 
00365                   /* Handle the error, if necessary. */
00366                   if ( bzError == BZ_IO_ERROR )
00367                         return TEKERR_FILE_IO;
00368             } else {
00369                   /* Do a read close. */
00370                   BZ2_bzReadClose(
00371                         &bzError,
00372                         this->PrivBZ2FileDesc
00373                   );
00374             }
00375 
00376             /* Handle any catastrophic errors. */
00377             if ( bzError != BZ_OK )
00378                   return TEKERR_UNEXPECTED;
00379 
00380             /* NULLify the stream descriptor. */
00381             this->PrivBZ2FileDesc = NULL;
00382       }
00383 
00384       /* Return to caller. */
00385       return TEKERR_OK;
00386 }
00387 
00388 
00395 TEKERR TekFileBZ2Binary::OpenStream()
00396 {
00397       BZFILE * NewStream;
00398       int bzError;
00399       int UseSmallMemory;
00400 
00401 #ifndef     NO_INTERNAL_NULL_CHECKS
00402       if ( this->PrivFileDesc == NULL )
00403             return TEKERR_SEQUENCE;
00404       if ( this->PrivBZ2FileDesc != NULL )
00405             return TEKERR_SEQUENCE;
00406 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00407 
00408       /* How should we open the stream? */
00409       if ( this->PrivFlags & TekFileBZ2Binary_Mode_WriteToFile )
00410       {
00411             //* Open a stream. */
00412             NewStream = BZ2_bzWriteOpen(
00413                   &bzError,
00414                   this->PrivFileDesc,
00415                   this->PrivBlockSize,
00416                   this->PrivVerbosity,
00417                   this->PrivWorkFactor
00418             );
00419       } else {
00420             /* Determine if SmallMemory is to be used. */
00421             if ( this->PrivFlags & TekFileBZ2Binary_Mode_UseLessMemory )
00422                   UseSmallMemory = 1;
00423             else
00424                   UseSmallMemory = 0;
00425 
00426             /* Open a stream. */
00427             NewStream = BZ2_bzReadOpen(
00428                   &bzError,
00429                   this->PrivFileDesc,
00430                   this->PrivVerbosity,
00431                   UseSmallMemory,
00432                   NULL,
00433                   0
00434             );
00435       }
00436 
00437       if ( NewStream == NULL )
00438             return TEKERR_FAIL;
00439 
00440       this->PrivBZ2FileDesc = NewStream;
00441 
00442       return TEKERR_OK;
00443 }
00444 
00445 
00451 TEKERR TekFileBZ2Binary::get_FILE(FILE ** FileDescriptor)
00452 {
00453 #ifndef     NO_INTERNAL_NULL_CHECKS
00454       if ( this->PrivBZ2FileDesc != NULL )
00455             return TEKERR_ACCESS;
00456 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00457 
00458 #ifndef     NO_SIZE_T_CHECKS
00459       if ( FileDescriptor == (FILE **)NULL )
00460             return TEKERR_POINTER;
00461 #endif      /* not NO_SIZE_T_CHECKS */
00462 
00463       *FileDescriptor = this->PrivFileDesc;
00464 
00465       return TEKERR_OK;
00466 }
00467 
00468 
00474 TEKERR TekFileBZ2Binary::get_Filename(uchar_t ** Name)
00475 {
00476       uchar_t * RetVal;
00477 
00478 #ifndef     NO_SIZE_T_CHECKS
00479       if ( Name == (uchar_t **)NULL )
00480             return TEKERR_POINTER;
00481 #endif      /* not NO_SIZE_T_CHECKS */
00482 
00483       /* Check to see if the constructor was able to allocate memory. */
00484       if ( this->PrivFilename.uchar_t_ascii == NULL )
00485             return TEKERR_MEMORY;
00486 
00487       if ( this->PrivFilename.uchar_t_ascii[0] == '\0' )
00488             return TEKERR_ACCESS;
00489 
00490       RetVal = char2uchar(this->PrivFilename.uchar_t_ascii);
00491       if ( RetVal == NULL )
00492             return TEKERR_MEMORY;
00493 
00494       *Name = RetVal;
00495 
00496       return TEKERR_OK;
00497 }
00498 
00499 
00510 TEKERR TekFileBZ2Binary::put_FILE(FILE * FileDescriptor)
00511 {
00512 #ifndef     NO_INTERNAL_NULL_CHECKS
00513       if ( this->PrivBZ2FileDesc != NULL )
00514             return TEKERR_ACCESS;
00515       if ( ( this->PrivFileDesc != NULL ) && ( FileDescriptor != NULL ) )
00516             return TEKERR_ACCESS;
00517 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00518 
00519       if ( ( FileDescriptor == NULL ) && ( this->PrivFileDesc != NULL ) )
00520       {
00521             if ( this->PrivBZ2FileDesc != NULL )
00522                   this->CloseStream();
00523             this->Close();
00524       }
00525 
00526       this->PrivFileDesc = FileDescriptor;
00527 
00528       return TEKERR_OK;
00529 }
00530 
00531 
00537 TEKERR TekFileBZ2Binary::put_Filename(uchar_t * Name)
00538 {
00539 #ifndef     NO_INTERNAL_NULL_CHECKS
00540       if ( this->PrivFileDesc != NULL )
00541             return TEKERR_ACCESS;
00542 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00543 
00544 #ifndef     NO_SIZE_T_CHECKS
00545       if ( Name == NULL )
00546             return TEKERR_POINTER;
00547 #endif      /* not NO_SIZE_T_CHECKS */
00548 
00549       /* Determine the length. */
00550       this->PrivFilename.uchar_t_asciilen =
00551         strlen(Name->uchar_t_ascii);
00552 
00553       /* Check to see if the constructor was able to allocate memory. */
00554       if ( this->PrivFilename.uchar_t_ascii == NULL )
00555             return TEKERR_MEMORY;
00556 
00557       /* Copy the Filename string. */
00558       strcpy(this->PrivFilename.uchar_t_ascii, Name->uchar_t_ascii);
00559 
00560       return TEKERR_OK;
00561 }
00562 
00563 
00569 TEKERR TekFileBZ2Binary::get_Type(TekFileType * FileTypePointer)
00570 {
00571 #ifndef     NO_SIZE_T_CHECKS
00572       if ( FileTypePointer == NULL )
00573             return TEKERR_POINTER;
00574 #endif      /* NO_SIZE_T_CHECKS */
00575 
00576       *FileTypePointer = TekFileType_BZIP2;
00577 
00578       return TEKERR_OK;
00579 }
00580 
00581 
00587 TEKERR TekFileBZ2Binary::Close()
00588 {
00589       struct i64 bzIn, bzOut;
00590       int bzError;
00591 
00592       /* Determine if there is a BZ2 Descriptor open. */
00593       if ( this->PrivBZ2FileDesc != NULL )
00594       {
00595             /* How should we close the stream? */
00596             if ( this->PrivFlags & TekFileBZ2Binary_Mode_WriteToFile )
00597             {
00598                   /* Do a write close. */
00599                   BZ2_bzWriteClose64(
00600                         &bzError,
00601                         this->PrivBZ2FileDesc,
00602                         0,
00603                         &bzIn.i64_a,
00604                         &bzIn.i64_b,
00605                         &bzOut.i64_a,
00606                         &bzOut.i64_b
00607                   );
00608                   /* Convert our data into uint64_t's. */
00609                   memcpy(&this->PrivBytesIn, &bzIn, 8);
00610                   memcpy(&this->PrivBytesOut, &bzOut, 8);
00611 
00612                   /* Handle the error, if necessary. */
00613                   if ( bzError == BZ_IO_ERROR )
00614                         return TEKERR_FILE_IO;
00615             } else {
00616                   /* Do a read close. */
00617                   BZ2_bzReadClose(
00618                         &bzError,
00619                         this->PrivBZ2FileDesc
00620                   );
00621             }
00622 
00623             /* Handle any catastrophic errors. */
00624             if ( bzError != BZ_OK )
00625                   return TEKERR_UNEXPECTED;
00626 
00627             /* NULLify the stream descriptor. */
00628             this->PrivBZ2FileDesc = NULL;
00629 
00630             if ( (this->PrivFlags & TekFileBZ2Binary_Mode_EndOfStream) != 0 )
00631                   this->PrivFlags ^= TekFileBZ2Binary_Mode_EndOfStream;
00632       }
00633 
00634       /* Determine if there is a FILE descriptor open. */
00635       if ( this->PrivFileDesc != NULL )
00636       {
00637             /* Close the descriptor. */
00638             if ( fclose(this->PrivFileDesc) != 0 )
00639             {
00640                   /* Handle the error. */
00641                   if ( errno == ENOSPC )
00642                         return TEKERR_FILE_DISKFULL;
00643                   else
00644                         return TEKERR_FILE_IO;
00645             }
00646 
00647             /* NULLify the FILE descriptor. */
00648             this->PrivFileDesc = NULL;
00649       }
00650 
00651       /* We're all done here. */
00652       return TEKERR_OK;
00653 }
00654 
00655 
00661 TEKERR TekFileBZ2Binary::get_Mode(TekFileMode * ModeID)
00662 {
00663 #ifndef     NO_SIZE_T_CHECKS
00664       if ( ModeID == NULL )
00665             return TEKERR_POINTER;
00666 #endif      /* NO_SIZE_T_CHECKS */
00667 
00668       /* Determine if the WriteToFile bit is set. */
00669       if ( this->PrivFlags && TekFileBZ2Binary_Mode_WriteToFile )
00670             *ModeID = TekFileMode_WriteOnly;
00671       else
00672             *ModeID = TekFileMode_ReadOnly;
00673 
00674       /* Return to caller. */
00675       return TEKERR_OK;
00676 }
00677 
00678 
00686 TEKERR TekFileBZ2Binary::put_Mode(TekFileMode ModeID)
00687 {
00688 #ifndef     NO_INTERNAL_NULL_CHECKS
00689       if ( this->PrivFileDesc != NULL )
00690             return TEKERR_ACCESS;
00691 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00692 
00693       /* Determine whether the flag needs to be set. */
00694       if ( ModeID != TekFileMode_ReadOnly )
00695       {
00696             this->PrivFlags |= TekFileBZ2Binary_Mode_WriteToFile;
00697       }
00698       else
00699       {
00700             if ( this->PrivFlags && TekFileBZ2Binary_Mode_WriteToFile )
00701                   this->PrivFlags ^= TekFileBZ2Binary_Mode_WriteToFile;
00702       }
00703 
00704       /* Return to caller. */
00705       return TEKERR_OK;
00706 }
00707 
00708 
00714 TEKERR TekFileBZ2Binary::Flush()
00715 {
00716       return TEKERR_NOTIMPL;
00717 }
00718 
00719 
00725 TEKERR TekFileBZ2Binary::Open()
00726 {
00727       BZFILE * NewStream;
00728       FILE * NewDesc;
00729       int bzError;
00730       int UseSmallMemory;
00731 
00732       /* Make sure the internal buffer isn't NULL. */
00733       if ( this->PrivFilename.uchar_t_ascii == NULL )
00734             return TEKERR_MEMORY;
00735 
00736       /* How should we open the stream? */
00737       if ( this->PrivFlags && TekFileBZ2Binary_Mode_WriteToFile )
00738       {
00739             /* Open the file for writing. */
00740             NewDesc = fopen(
00741                   this->PrivFilename.uchar_t_ascii,
00742                   "wb"
00743             );
00744             if ( NewDesc == NULL )
00745                   return TEKERR_FILE_IO;
00746 
00747             /* Open a stream. */
00748             NewStream = BZ2_bzWriteOpen(
00749                   &bzError,
00750                   NewDesc,
00751                   this->PrivBlockSize,
00752                   this->PrivVerbosity,
00753                   this->PrivWorkFactor
00754             );
00755       } else {
00756             /* Open the file for reading. */
00757             NewDesc = fopen(
00758                   this->PrivFilename.uchar_t_ascii,
00759                   "rb"
00760             );
00761             if ( NewDesc == NULL )
00762                   return TEKERR_FILE_IO;
00763 
00764             if ( this->PrivFlags & TekFileBZ2Binary_Mode_UseLessMemory )
00765                   UseSmallMemory = 1;
00766             else
00767                   UseSmallMemory = 0;
00768 
00769             /* Open a stream. */
00770             NewStream = BZ2_bzReadOpen(
00771                   &bzError,
00772                   NewDesc,
00773                   this->PrivVerbosity,
00774                   UseSmallMemory,
00775                   NULL,
00776                   0
00777             );
00778       }
00779 
00780       /* Handle errors. */
00781       if ( bzError != BZ_OK )
00782       {
00783             fclose(NewDesc);
00784             switch ( bzError )
00785             {
00786                   case BZ_IO_ERROR:
00787                         return TEKERR_FILE_IO;
00788                   case BZ_MEM_ERROR:
00789                         return TEKERR_MEMORY;
00790                   case BZ_CONFIG_ERROR:
00791                   case BZ_PARAM_ERROR:
00792                   default:
00793                         return TEKERR_UNEXPECTED;
00794             }
00795       }
00796 
00797       /* Set up our internal pointers. */
00798       this->PrivFileDesc = NewDesc;
00799       this->PrivBZ2FileDesc = NewStream;
00800 
00801       /* Return to caller. */
00802       return TEKERR_OK;
00803 }
00804 
00805 
00811 TEKERR TekFileBZ2Binary::Open64()
00812 {
00813       BZFILE * NewStream;
00814       FILE * NewDesc;
00815       int bzError;
00816       int UseSmallMemory;
00817 
00818       /* Make sure the internal buffer isn't NULL. */
00819       if ( this->PrivFilename.uchar_t_ascii == NULL )
00820             return TEKERR_MEMORY;
00821 
00822       /* How should we open the stream? */
00823       if ( this->PrivFlags && TekFileBZ2Binary_Mode_WriteToFile )
00824       {
00825             /* Open the file for writing. */
00826             NewDesc = fopen64(
00827                   this->PrivFilename.uchar_t_ascii,
00828                   "wb"
00829             );
00830             if ( NewDesc == NULL )
00831                   return TEKERR_FILE_IO;
00832 
00833             /* Open a stream. */
00834             NewStream = BZ2_bzWriteOpen(
00835                   &bzError,
00836                   NewDesc,
00837                   this->PrivBlockSize,
00838                   this->PrivVerbosity,
00839                   this->PrivWorkFactor
00840             );
00841       } else {
00842             /* Open the file for reading. */
00843             NewDesc = fopen64(
00844                   this->PrivFilename.uchar_t_ascii,
00845                   "rb"
00846             );
00847             if ( NewDesc == NULL )
00848                   return TEKERR_FILE_IO;
00849 
00850             if ( this->PrivFlags & TekFileBZ2Binary_Mode_UseLessMemory )
00851                   UseSmallMemory = 1;
00852             else
00853                   UseSmallMemory = 0;
00854 
00855             /* Open a stream. */
00856             NewStream = BZ2_bzReadOpen(
00857                   &bzError,
00858                   NewDesc,
00859                   this->PrivVerbosity,
00860                   UseSmallMemory,
00861                   NULL,
00862                   0
00863             );
00864       }
00865 
00866       /* Handle errors. */
00867       if ( bzError != BZ_OK )
00868       {
00869             fclose(NewDesc);
00870             switch ( bzError )
00871             {
00872                   case BZ_IO_ERROR:
00873                         return TEKERR_FILE_IO;
00874                   case BZ_MEM_ERROR:
00875                         return TEKERR_MEMORY;
00876                   case BZ_CONFIG_ERROR:
00877                   case BZ_PARAM_ERROR:
00878                   default:
00879                         return TEKERR_UNEXPECTED;
00880             }
00881       }
00882 
00883       /* Set up our internal pointers. */
00884       this->PrivFileDesc = NewDesc;
00885       this->PrivBZ2FileDesc = NewStream;
00886 
00887       /* Return to caller. */
00888       return TEKERR_OK;
00889 }
00890 
00891 
00897 TEKERR TekFileBZ2Binary::Read64(void * Buffer, uint64_t BytesToRead, uint64_t * BytesRead)
00898 {
00899       return TEKERR_NOTIMPL;
00900 }
00901 
00902 
00908 TEKERR TekFileBZ2Binary::Read(void * Buffer, unsigned long BytesToRead, unsigned long * BytesRead)
00909 {
00910       unsigned long BytesWeRead;
00911       int bzError;
00912 
00913 #ifndef     NO_SIZE_T_CHECKS
00914       if ( Buffer == NULL )
00915             return TEKERR_POINTER;
00916 #endif      /* NO_SIZE_T_CHECKS */
00917 
00918       /* Determine if we ended up with a buffer situation. */
00919       if ( this->PrivFlags & TekFileBZ2Binary_Mode_EndOfStream )
00920       {
00921             /* Determine if we are at the end. */
00922             if ( BytesToRead >= (unsigned long)this->PrivUnusedLen )
00923             {
00924                   memcpy(Buffer, this->PrivUnused, this->PrivUnusedLen);
00925                   if ( BytesRead != NULL )
00926                         *BytesRead = this->PrivUnusedLen;
00927                   return TEKERR_FILE_EOF;
00928             } else {
00929                   memcpy(Buffer, this->PrivUnused, BytesToRead);
00930                   this->PrivUnused += BytesToRead;
00931                   this->PrivUnusedLen -= BytesToRead;
00932 
00933                   if ( BytesRead != NULL )
00934                         *BytesRead = this->PrivUnusedLen;
00935             }
00936       } else {
00937             /* Read next area in the stream. */
00938             BytesWeRead = (unsigned long)BZ2_bzRead(
00939                   &bzError,
00940                   this->PrivBZ2FileDesc,
00941                   Buffer,
00942                   BytesToRead
00943             );
00944             if ( BytesRead != NULL )
00945                   *BytesRead = BytesWeRead;
00946 
00947             /* Handle errors. */
00948             if ( bzError != BZ_OK )
00949             {
00950                   switch ( bzError )
00951                   {
00952                   case BZ_STREAM_END:
00953                         /* If we're here, we reached end of stream. */
00954                         this->PrivFlags |= TekFileBZ2Binary_Mode_EndOfStream;
00955                         BZ2_bzReadGetUnused(
00956                               &bzError,
00957                               this->PrivBZ2FileDesc,
00958                               (void**)&this->PrivUnused,
00959                               &this->PrivUnusedLen
00960                         );
00961                         if ( bzError != BZ_OK )
00962                               return TEKERR_UNEXPECTED;
00963                         if ( this->PrivUnusedLen == 0 )
00964                               return TEKERR_FILE_EOF;
00965                         break;
00966                   case BZ_MEM_ERROR:
00967                         return TEKERR_MEMORY;
00968                   case BZ_IO_ERROR:
00969                         return TEKERR_FILE_IO;
00970                   case BZ_DATA_ERROR:
00971                   case BZ_DATA_ERROR_MAGIC:
00972                   case BZ_UNEXPECTED_EOF:
00973                   case BZ_SEQUENCE_ERROR:
00974                   case BZ_PARAM_ERROR:
00975                   default:
00976                         return TEKERR_UNEXPECTED;
00977                   }
00978             }
00979       }
00980 
00981       /* Return to caller. */
00982       return TEKERR_OK;
00983 }
00984 
00985 
00991 TEKERR TekFileBZ2Binary::Seek64(TekFileSeek SeekWhere, int64_t NewLocation)
00992 {
00993       return TEKERR_NOTIMPL;
00994 }
00995 
00996 
01002 TEKERR TekFileBZ2Binary::Seek(TekFileSeek SeekWhere, signed long NewLocation)
01003 {
01004       return TEKERR_NOTIMPL;
01005 }
01006 
01007 
01013 TEKERR TekFileBZ2Binary::Write64(void * Buffer, uint64_t BytesToWrite, uint64_t * BytesWrote)
01014 {
01015       return TEKERR_NOTIMPL;
01016 }
01017 
01018 
01024 TEKERR TekFileBZ2Binary::Write(void * Buffer, unsigned long BytesToWrite, unsigned long * BytesWrote)
01025 {
01026       BZFILE * bzdesc;
01027       int bzError;
01028 
01029 #ifndef     NO_SIZE_T_CHECKS
01030       if ( Buffer == NULL )
01031             return TEKERR_POINTER;
01032 #endif      /* NO_SIZE_T_CHECKS */
01033 
01034       bzdesc = this->PrivBZ2FileDesc;
01035       /* Write out the buffer. */
01036       BZ2_bzWrite(&bzError, bzdesc, Buffer, BytesToWrite);
01037       /* Handle any errors. */
01038       if ( bzError != BZ_OK )
01039       {
01040             switch ( bzError )
01041             {
01042                   case BZ_SEQUENCE_ERROR:
01043                         return TEKERR_SEQUENCE;
01044                   case BZ_IO_ERROR:
01045                         if ( errno == ENOSPC )
01046                               return TEKERR_FILE_DISKFULL;
01047                         return TEKERR_FILE_IO;
01048                   case BZ_PARAM_ERROR:
01049                   default:
01050                         return TEKERR_UNEXPECTED;
01051             }
01052       }
01053 
01054       /* Set *BytesWrote. */
01055       if ( BytesWrote != NULL )
01056             *BytesWrote = BytesToWrite;
01057 
01058       /* Return to caller. */
01059       return TEKERR_OK;
01060 }
01061 
01062 
01073 TEKERR TekFileBZ2Binary::get_Location(unsigned long * Location)
01074 {
01075       return TEKERR_NOTIMPL;
01076 }
01077 
01078 
01089 TEKERR TekFileBZ2Binary::get_Location64(uint64_t * Location)
01090 {
01091       return TEKERR_NOTIMPL;
01092 }
01093 
01094 
SourceForge.net Logo  Technical Library Template Interface Project Page