TekFileBinary.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 #define     LIBTEKLTI_EXPORT  (0)
00022 
00023 #ifndef     _cplusplus
00024 #define     _cplusplus
00025 #endif      /* _cplusplus */
00026 #include "teklti.h"
00027 
00028 #include <limits.h>
00029 #include <errno.h>
00030 
00031 MKTEKUUID(UTekFileBinary, "d60710c0-e5ea-11d9-8325-000bdbc434d9")
00032 MKTEKDEBUGSTRING(DBTekFileBinary, "TekFileBinary")
00033 
00034 
00035 #ifndef     USE_386_ASM
00036 
00040 TekFileBinary::TekFileBinary()
00041 {
00042       //TEKSTD_IMPLEMENT_BEGIN(UTekFileBinary)
00043       TEKSTD_IMPLEMENT_INTERFACE(UTekFile)
00044       TEKSTD_IMPLEMENT_INTERFACE(UTekFileBinary)
00045       TEKSTD_IMPLEMENT_ENDBASE
00046 
00047       this->PrivFileName.uchar_t_ascii = NULL;
00048       this->PrivFileName.uchar_t_asciilen = 0;
00049       this->PrivFileDesc = NULL;
00050       PrivFileMode = TekFileMode_ReadOnly;
00051       PrivTekFileType = TekFileType_Binary;
00052 }
00053 
00054 
00058 TekFileBinary::~TekFileBinary()
00059 {
00060       if ( this->PrivFileDesc != NULL )
00061             fclose(this->PrivFileDesc);
00062       if ( this->PrivFileName.uchar_t_ascii != NULL )
00063             free(this->PrivFileName.uchar_t_ascii);
00064 }
00065 
00066 
00067 const char TekFileBinary_ReadOnly[] = "rb";
00068 const char TekFileBinary_WriteOnly[] = "wb";
00069 const char TekFileBinary_Append[] = "ab";
00070 const char TekFileBinary_ReadWrite[] = "r+b";
00071 const char TekFileBinary_ReadWriteTrunc[] = "w+b";
00072 const char TekFileBinary_ReadAppend[] = "a+b";
00073 
00081 TEKERR TekFileBinary::ConvertToPipe()
00082 {
00083       this->PrivTekFileType = TekFileType_BinaryPipe;
00084       return TEKERR_OK;
00085 }
00086 
00092 TEKERR TekFileBinary::get_FILE(FILE ** FileDescriptor)
00093 {
00094 #ifndef     NO_SIZE_T_CHECKS
00095       if ( FileDescriptor == NULL )
00096             return TEKERR_POINTER;
00097 #endif      /* not NO_SIZE_T_CHECKS */
00098 
00099       *FileDescriptor = this->PrivFileDesc;
00100       
00101       return TEKERR_OK;
00102 }
00103 
00104 
00110 TEKERR TekFileBinary::get_Filename(uchar_t ** Name)
00111 {
00112       uchar_t * newval;
00113       
00114 #ifndef     NO_SIZE_T_CHECKS
00115       if ( Name == NULL )
00116             return TEKERR_POINTER;
00117 #endif      /* not NO_SIZE_T_CHECKS */
00118 
00119 #ifndef     NO_INTERNAL_NULL_CHECKS
00120       if ( this->PrivFileName.uchar_t_ascii == NULL )
00121             return TEKERR_UNEXPECTED;
00122 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00123 
00124       /* Convert our ASCII string to a uchar. */
00125       newval = char2uchar(this->PrivFileName.uchar_t_ascii);
00126       if ( newval == NULL )
00127             return TEKERR_MEMORY;
00128 
00129       /* Set up our uchar. */
00130       *Name = newval;
00131 
00132       /* Return to caller. */
00133       return TEKERR_OK;
00134 }
00135 
00136 
00144 TEKERR TekFileBinary::put_FILE(FILE * FileDescriptor)
00145 {
00146       this->PrivFileDesc = FileDescriptor;
00147       
00148       return TEKERR_OK;
00149 }
00150 
00151 
00157 TEKERR TekFileBinary::put_Filename(uchar_t * Name)
00158 {
00159 #ifndef     NO_SIZE_T_CHECKS
00160       if ( Name == NULL )
00161             return TEKERR_POINTER;
00162 #endif      /* not NO_SIZE_T_CHECKS */
00163 
00164       this->PrivFileName.uchar_t_ascii = strdup(uchar2char(Name));
00165 
00166       return TEKERR_OK;
00167 }
00168 
00169 
00175 TEKERR TekFileBinary::get_Type(TekFileType * FileTypePointer)
00176 {
00177       TekFileType * retval;
00178 
00179       retval = FileTypePointer;
00180 
00181 #ifndef     NO_SIZE_T_CHECKS
00182       if ( FileTypePointer == NULL )
00183             return TEKERR_POINTER;
00184 #endif      /* not NO_SIZE_T_CHECKS */
00185 
00186       retval[0] = this->PrivTekFileType;
00187 
00188       return TEKERR_OK;
00189 }
00190 
00191 
00197 TEKERR TekFileBinary::Close()
00198 {
00199       int err;
00200 
00201 #ifndef     NO_INTERNAL_NULL_CHECKS
00202       if ( this->PrivFileDesc == NULL )
00203             return TEKERR_SEQUENCE;
00204 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00205 
00206       err = fclose(this->PrivFileDesc);
00207 
00208       if ( err != 0 )
00209       {
00210             switch ( err )
00211             {
00212                   case ENOSPC:
00213                         return TEKERR_FILE_DISKFULL;
00214                   case EIO:
00215                   case EPIPE:
00216                         return TEKERR_FILE_IO;
00217                   default:
00218                         return TEKERR_UNEXPECTED;
00219             }
00220       }
00221 
00222       this->PrivFileDesc = NULL;
00223 
00224       return TEKERR_OK;
00225 }
00226 
00227 
00233 TEKERR TekFileBinary::get_Mode(TekFileMode * ModeID)
00234 {
00235 #ifndef     NO_SIZE_T_CHECKS
00236       if ( ModeID == NULL )
00237             return TEKERR_POINTER;
00238 #endif      /* not NO_SIZE_T_CHECKS */
00239 
00240       *ModeID = this->PrivFileMode;
00241 
00242       return TEKERR_OK;
00243 }
00244 
00245 
00251 TEKERR TekFileBinary::Flush()
00252 {
00253       int err;
00254 
00255 #ifndef     NO_INTERNAL_NULL_CHECKS
00256       if ( this->PrivFileDesc == NULL )
00257             return TEKERR_SEQUENCE;
00258 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00259 
00260       err = fflush(this->PrivFileDesc);
00261 
00262       if ( err != 0 )
00263       {
00264             switch ( err )
00265             {
00266                   case ENOSPC:
00267                         return TEKERR_FILE_DISKFULL;
00268                   case EIO:
00269                   case EPIPE:
00270                         return TEKERR_FILE_IO;
00271                   default:
00272                         return TEKERR_UNEXPECTED;
00273             }
00274       }
00275 
00276       return TEKERR_OK;
00277 }
00278 
00279 
00285 TEKERR TekFileBinary::Open()
00286 {
00287       const char * tmpopenvar;
00288 
00289       /* Make sure this instance does not have a file already open. */
00290 #ifndef     NO_INTERNAL_NULL_CHECKS
00291       if ( this->PrivFileDesc != NULL )
00292             return TEKERR_SEQUENCE;
00293 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00294 
00295       /* Figure out what fopen() op are going to do. */
00296       switch ( this->PrivFileMode )
00297       {
00298             case TekFileMode_WriteOnly:
00299                   tmpopenvar = TekFileBinary_WriteOnly;
00300                   break;
00301             case TekFileMode_Append:
00302                   tmpopenvar = TekFileBinary_Append;
00303                   break;
00304             case TekFileMode_ReadWrite:
00305                   tmpopenvar = TekFileBinary_ReadWrite;
00306                   break;
00307             case TekFileMode_ReadWriteTrunc:
00308                   tmpopenvar = TekFileBinary_ReadWriteTrunc;
00309                   break;
00310             case TekFileMode_ReadAppend:
00311                   tmpopenvar = TekFileBinary_ReadAppend;
00312                   break;
00313             default:
00314                   tmpopenvar = TekFileBinary_ReadOnly;
00315                   break;
00316       }
00317 
00318       /* Open the file. */
00319       this->PrivFileDesc = fopen(
00320             this->PrivFileName.uchar_t_ascii,
00321             tmpopenvar
00322       );
00323       if ( this->PrivFileDesc == NULL )
00324             return TEKERR_FAIL;
00325 
00326       /* Return to caller. */
00327       return TEKERR_OK;
00328 }
00329 
00330 
00336 TEKERR TekFileBinary::Open64()
00337 {
00338 #ifndef     OPEN64_NOT_SUPPORTED
00339       const char * tmpopenvar;
00340 
00341       /* Make sure this instance does not have a file already open. */
00342 #ifndef     NO_INTERNAL_NULL_CHECKS
00343       if ( this->PrivFileDesc != NULL )
00344             return TEKERR_SEQUENCE;
00345 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00346 
00347       /* Figure out what fopen() op are going to do. */
00348       switch ( this->PrivFileMode )
00349       {
00350             case TekFileMode_ReadOnly:
00351                   tmpopenvar = TekFileBinary_ReadOnly;
00352                   break;
00353             case TekFileMode_WriteOnly:
00354                   tmpopenvar = TekFileBinary_WriteOnly;
00355                   break;
00356             case TekFileMode_Append:
00357                   tmpopenvar = TekFileBinary_Append;
00358                   break;
00359             case TekFileMode_ReadWrite:
00360                   tmpopenvar = TekFileBinary_ReadWrite;
00361                   break;
00362             case TekFileMode_ReadWriteTrunc:
00363                   tmpopenvar = TekFileBinary_ReadWriteTrunc;
00364                   break;
00365             case TekFileMode_ReadAppend:
00366                   tmpopenvar = TekFileBinary_ReadAppend;
00367                   break;
00368             default:
00369                   return TEKERR_UNAVAILABLE;
00370       }
00371 
00372       /* Open the file. */
00373       this->PrivFileDesc = fopen64(
00374             this->PrivFileName.uchar_t_ascii,
00375             tmpopenvar
00376       );
00377       if ( this->PrivFileDesc == NULL )
00378             return TEKERR_FAIL;
00379 
00380       /* Return to caller. */
00381       return TEKERR_OK;
00382 #else /* OPEN64_NOT_SUPPORTED */
00383       return TEKERR_NOTIMPL;
00384 #endif      /* OPEN64_NOT_SUPPORTED */
00385 }
00386 
00387 
00393 TEKERR TekFileBinary::put_Mode(TekFileMode ModeID)
00394 {
00395 #ifndef     NO_INTERNAL_NULL_CHECKS
00396       if ( this->PrivFileDesc != NULL )
00397             return TEKERR_ACCESS;
00398 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00399 
00400       this->PrivFileMode = ModeID;
00401       return TEKERR_OK;
00402 }
00403 
00404 
00410 TEKERR TekFileBinary::Read64(void * Buffer, uint64_t BytesToRead, uint64_t * BytesRead)
00411 {
00412       return TEKERR_NOTIMPL;
00413 }
00414 
00415 
00421 TEKERR TekFileBinary::Read(void * Buffer, unsigned long BytesToRead, unsigned long * BytesRead)
00422 {
00423       size_t bytesread;
00424 
00425 #ifndef     NO_SIZE_T_CHECKS
00426       if ( Buffer == NULL )
00427             return TEKERR_POINTER;
00428 #endif      /* not NO_SIZE_T_CHECKS */
00429 
00430 #ifndef     NO_INTERNAL_NULL_CHECKS
00431       if ( this->PrivFileDesc == NULL )
00432             return TEKERR_SEQUENCE;
00433 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00434 
00435       /* Write the buffer to the file. */
00436       bytesread = fread(Buffer, sizeof(char), BytesToRead, this->PrivFileDesc);
00437 
00438       /* Put the result into BytesWrote. */
00439       *BytesRead = bytesread;
00440 
00441       /* Check for success or failure. */
00442       if ( bytesread > 0 )
00443             return TEKERR_OK;
00444 
00445       /* Check for EOF error. */
00446       if ( feof(this->PrivFileDesc) != 0 )
00447             return TEKERR_FILE_EOF;
00448 
00449       /* Check for EPIPE error. */
00450       if ( errno == EPIPE )
00451             return TEKERR_FILE_PIPE;
00452 
00453       /* All other errors are considered IO errors. */
00454       return TEKERR_FILE_IO;
00455 }
00456 
00457 
00463 TEKERR TekFileBinary::Seek64(TekFileSeek SeekWhere, int64_t NewLocation)
00464 {
00465       return TEKERR_NOTIMPL;
00466 }
00467 
00468 
00474 TEKERR TekFileBinary::Seek(TekFileSeek SeekWhere, signed long NewLocation)
00475 {
00476       int SeekWhence;
00477 
00478 #ifndef     NO_INTERNAL_NULL_CHECKS
00479       if ( this->PrivFileDesc == NULL )
00480             return TEKERR_SEQUENCE;
00481 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00482 
00483       switch ( SeekWhere )
00484       {
00485             case TekFileSeek_Begin:
00486                   SeekWhence = SEEK_SET;
00487                   break;
00488             case TekFileSeek_Current:
00489                   SeekWhence = SEEK_CUR;
00490                   break;
00491             case TekFileSeek_End:
00492                   SeekWhence = SEEK_END;
00493                   break;
00494             default:
00495                   return TEKERR_UNAVAILABLE;
00496       }
00497 
00498       if ( fseek(this->PrivFileDesc, NewLocation, SeekWhence) )
00499             return TEKERR_FAIL;
00500 
00501       return TEKERR_OK;
00502 }
00503 
00504 
00510 TEKERR TekFileBinary::Write64(void * Buffer, uint64_t BytesToWrite, uint64_t * BytesWrote)
00511 {
00512       return TEKERR_NOTIMPL;
00513 }
00514 
00515 
00521 TEKERR TekFileBinary::Write(void * Buffer, unsigned long BytesToWrite, unsigned long * BytesWrote)
00522 {
00523       size_t written;
00524 
00525 #ifndef     NO_SIZE_T_CHECKS
00526       if ( Buffer == NULL )
00527             return TEKERR_POINTER;
00528 #endif      /* not NO_SIZE_T_CHECKS */
00529 
00530 #ifndef     NO_INTERNAL_NULL_CHECKS
00531       if ( this->PrivFileDesc == NULL )
00532             return TEKERR_SEQUENCE;
00533 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00534 
00535       /* Write the buffer to the file. */
00536       written = fwrite(Buffer, sizeof(char), BytesToWrite, this->PrivFileDesc);
00537 
00538       /* Put the result into BytesWrote. */
00539       *BytesWrote = written;
00540 
00541       /* Check for success or failure. */
00542       if ( written == BytesToWrite )
00543             return TEKERR_OK;
00544 
00545       /* We have to find out what the error is. */
00546       switch ( errno )
00547       {
00548             case EPIPE:
00549                   return TEKERR_FILE_PIPE;
00550             case ENOSPC:
00551                   return TEKERR_FILE_DISKFULL;
00552             case EBADF:
00553                   /* Check for read-only status. */
00554                   if ( this->PrivFileMode == TekFileMode_ReadOnly )
00555                         return TEKERR_FILE_READONLY;
00556             case EIO:
00557             default:
00558                   return TEKERR_FILE_IO;
00559       }
00560 }
00561 
00562 
00569 TEKERR TekFileBinary::get_Location(unsigned long * Location)
00570 {
00571       long loc;
00572 
00573 #ifndef     NO_INTERNAL_NULL_CHECKS
00574       if ( this->PrivFileDesc == NULL )
00575             return TEKERR_SEQUENCE;
00576 #endif      /* not NO_INTERNAL_NULL_CHECKS */
00577 
00578       /* Get the current file position. */
00579       loc = ftell(this->PrivFileDesc);
00580 
00581       /* Check for error. */
00582       if ( loc != -1 )
00583       {
00584             /* Move location to memory referenced by Location. */
00585             *Location = (unsigned long)loc;
00586 
00587             /* Indicate success. */
00588             return TEKERR_OK;
00589       }
00590 
00591       /* See if this is a pipe error. */
00592       if ( errno != EPIPE )
00593             return TEKERR_FILE_IO;
00594 
00595       return TEKERR_FILE_PIPE;
00596 }
00597 
00598 
00605 TEKERR TekFileBinary::get_Location64(uint64_t * Location)
00606 {
00607       return TEKERR_NOTIMPL;
00608 }
00609 
00610 #endif      /* not USE_386_ASM */
00611 
SourceForge.net Logo  Technical Library Template Interface Project Page