cgma
CubitFileIOWrapper.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002     COPYRIGHT 2002 CATERPILLAR INC.  ALL RIGHTS RESERVED
00003 
00004     This program is the property of Caterpillar Inc., includes Caterpillar's
00005     confidential and trade secret information, and is maintained as an
00006     unpublished copyrighted work.  It is not to be copied or used by others
00007     except under license from Caterpillar.  This program is also protected as an
00008     unpublished work in accordance with the copyright act of 1976.  In the event
00009     of either inadvertent or deliberate publication, Caterpillar Inc. intends to
00010     maintain copyright protection for this work under the relevant copyright
00011     laws pertaining to published works.  The inclusion of a copyright notice
00012     hereon is precautionary only, and does not imply publication or disclosure.
00013 
00014  
00015  Filename      : CubitFileIOWrapper.cpp
00016 
00017  Purpose       : Encapsulates file I/O operations for the Cubit file.
00018            
00019  Special Notes :
00020 
00021  Creator       : Will A. Helden
00022 
00023  Creation Date : 02/15/02
00024 
00025  Owner         : Will A. Helden
00026 
00027 *******************************************************************************/
00028 
00029 #include "CubitFileIOWrapper.hpp"
00030 #include <cstring>
00031 
00032 using namespace NCubitFile;
00033 
00035 // CIOWrapper -
00037 
00038 CIOWrapper::CIOWrapper(FILE* xpFile, UnsignedInt32 xintSourceEndian)
00039 {
00040     if(!xpFile)
00041         throw CCubitFile::ePassedNullPointer;
00042     mpFile = xpFile;
00043     mintSwapEndian = (xintSourceEndian != CCubitFile::mintNativeEndian);
00044     mintBlockStart = mintBlockEnd = 0;
00045 }
00046 
00047 CIOWrapper::CIOWrapper(UnsignedInt32 swap_endian, FILE* xpFile )
00048 {
00049     if(!xpFile)
00050         throw CCubitFile::ePassedNullPointer;
00051     mpFile = xpFile;
00052     mintSwapEndian = swap_endian;
00053     mintBlockStart = mintBlockEnd = 0;
00054 }
00055 
00056 
00057 CIOWrapper::CIOWrapper(FILE* xpFile, UnsignedInt32 xintAbsoluteOffset,
00058                        UnsignedInt32 xintRelativeOffset)
00059 {
00060     if(!xpFile)
00061         throw CCubitFile::ePassedNullPointer;
00062     mpFile = xpFile;
00063     mintBlockStart = mintBlockEnd = 0;
00064 
00065     if(NCubitFile::SetLocation(mpFile, xintAbsoluteOffset + xintRelativeOffset, SEEK_SET))
00066         throw CCubitFile::eFileSeekError;
00067     UnsignedInt32 lintSourceEndian;
00068     if(fread(&lintSourceEndian, sizeof(UnsignedInt32), 1, mpFile) != 1)
00069         throw CCubitFile::eFileReadError;
00070     mintSwapEndian = (lintSourceEndian != CCubitFile::mintNativeEndian);
00071 }
00072 
00073 CIOWrapper::~CIOWrapper()
00074 {
00075 }
00076 
00077         
00078 UnsignedInt32 CIOWrapper::BeginWriteBlock(UnsignedInt32 xintAbsoluteOffset)
00079 // Begin the write of a continuous data block, return the location in the file
00080 // where the block begins as a relative offset from the passed value (or
00081 // absolute offset if the passed offset is 0).
00082 {
00083     if(NCubitFile::SetLocation(mpFile, 0, SEEK_END))
00084         throw CCubitFile::eFileSeekError;
00085     UnsignedInt32 pos;
00086     mintBlockEnd = mintBlockStart = pos = NCubitFile::GetLocation(mpFile);
00087     return mintBlockStart - xintAbsoluteOffset;
00088 }
00089 
00090 void CIOWrapper::BeginRewriteBlock(UnsignedInt32 xintAbsoluteOffset,
00091                                    UnsignedInt32 xintRelativeOffset)
00092 {
00093     mintBlockEnd = mintBlockStart = xintAbsoluteOffset + xintRelativeOffset;
00094     if(NCubitFile::SetLocation(mpFile, mintBlockStart, SEEK_SET))
00095         throw CCubitFile::eFileSeekError;
00096 }
00097 
00098 void CIOWrapper::Write(const UnsignedInt32* xpaintData, UnsignedInt32 xintCount)
00099 {
00100     if(fwrite(xpaintData, sizeof(UnsignedInt32), xintCount, mpFile) != xintCount)
00101         throw CCubitFile::eFileWriteError;
00102     mintBlockEnd += (sizeof(UnsignedInt32) * xintCount);
00103 }
00104 
00105 void CIOWrapper::Write(const char* xpachrData, UnsignedInt32 xintCount,
00106                        UnsignedInt32 xint32bitPadded)
00107 {
00108     if(xintCount) {
00109         if(fwrite(xpachrData, sizeof(char), xintCount, mpFile) != xintCount)
00110             throw CCubitFile::eFileWriteError;
00111     }
00112     UnsignedInt32 lintMod = 0;
00113     if(xint32bitPadded) {
00114         lintMod = (xintCount % sizeof(UnsignedInt32));
00115         if(lintMod) {
00116             lintMod = sizeof(UnsignedInt32) - lintMod;
00117             if(fwrite("\0\0\0\0", sizeof(char), lintMod, mpFile) != lintMod)
00118                 throw CCubitFile::eFileWriteError;
00119         }
00120     }
00121     mintBlockEnd += (sizeof(char) * (xintCount + lintMod));
00122 }
00123 
00124 void CIOWrapper::Write(const double* xpadblData, UnsignedInt32 xintCount)
00125 {
00126     if(fwrite(xpadblData, sizeof(double), xintCount, mpFile) != xintCount)
00127         throw CCubitFile::eFileWriteError;
00128     mintBlockEnd += (sizeof(double) * xintCount);
00129 }
00130 
00131 void CIOWrapper::Write(const char* xpachrData)
00132 // Write a null terminated string to the data block, the strings length is 
00133 // written first, followed by the data and padding to keep the file pointer on
00134 // a word boundary (for ease of debugging).
00135 {
00136     UnsignedInt32 lintLength = xpachrData ? std::strlen(xpachrData) : 0;
00137     UnsignedInt32 lintMod = (lintLength % sizeof(UnsignedInt32));
00138     if(fwrite(&lintLength, sizeof(UnsignedInt32), 1, mpFile) != 1)
00139         throw CCubitFile::eFileWriteError;
00140     if(lintLength) {
00141         if(fwrite(xpachrData, sizeof(char), lintLength, mpFile) != lintLength)
00142             throw CCubitFile::eFileWriteError;
00143         if(lintMod) {
00144             lintMod = sizeof(UnsignedInt32) - lintMod;
00145             if(fwrite("\0\0\0\0", sizeof(char),  lintMod, mpFile) != lintMod)
00146                 throw CCubitFile::eFileWriteError;
00147         }
00148     }
00149     mintBlockEnd +=
00150         (sizeof(UnsignedInt32) + sizeof(char) * (lintLength + lintMod));
00151 }
00152 
00153 UnsignedInt32 CIOWrapper::EndWriteBlock()
00154 // Completes the writing of a contiguous data block, checks for errors and
00155 // returns the length of the block.
00156 {
00157     UnsignedInt32 lintBlockEnd = NCubitFile::GetLocation(mpFile);
00158     if((UnsignedInt32)lintBlockEnd != mintBlockEnd)
00159         throw CCubitFile::eCorruptBlock;
00160     UnsignedInt32 lintLength = mintBlockEnd - mintBlockStart;
00161     mintBlockEnd = mintBlockStart = 0;
00162     return lintLength;
00163 }
00164 
00165 
00166 void CIOWrapper::BeginReadBlock(UnsignedInt32 xintAbsoluteOffset,
00167                                 UnsignedInt32 xintRelativeOffset)
00168 // Begin the read of a contiguous data block.
00169 {
00170     if(NCubitFile::SetLocation(mpFile, xintAbsoluteOffset + xintRelativeOffset, SEEK_SET))
00171         throw CCubitFile::eFileSeekError;
00172 }
00173 
00174 void CIOWrapper::Read(UnsignedInt32* xpaintData, UnsignedInt32 xintCount)
00175 {
00176     if(fread(xpaintData, sizeof(UnsignedInt32), xintCount, mpFile) != xintCount)
00177         throw CCubitFile::eFileReadError;
00178     if(mintSwapEndian)
00179         SwapEndian<UnsignedInt32>(xintCount, xpaintData);
00180 }
00181 
00182 void CIOWrapper::Read(char* xpachrData, UnsignedInt32 xintCount,
00183                       UnsignedInt32 xint32bitPadded)
00184 {
00185     if(xintCount) {
00186         if(fread(xpachrData, sizeof(char), xintCount, mpFile) != xintCount)
00187             throw CCubitFile::eFileReadError;
00188     }
00189     if(xint32bitPadded) {
00190         char lachrPad[8]; // , *lpachrData = NULL;
00191         UnsignedInt32 lintMod = (xintCount % sizeof(UnsignedInt32));
00192         if(lintMod) {
00193             lintMod = sizeof(UnsignedInt32) - lintMod;
00194             if(fread(&lachrPad, sizeof(char), lintMod, mpFile) != lintMod)
00195                 throw CCubitFile::eFileReadError;
00196         }
00197     }
00198 }
00199 
00200 void CIOWrapper::Read(double* xpadblData, UnsignedInt32 xintCount)
00201 {
00202     if(fread(xpadblData, sizeof(double), xintCount, mpFile) != xintCount)
00203         throw CCubitFile::eFileReadError;
00204     if(mintSwapEndian)
00205         SwapEndian<double>(xintCount, xpadblData);
00206 }
00207 
00208 char* CIOWrapper::Read()
00209 // Read a null terminated string from the data block, the string's length is 
00210 // read first, followed by the data and then any padding.
00211 {
00212     UnsignedInt32 lintLength, lintMod;
00213     char lachrPad[8], *lpachrData = NULL;
00214     if(fread(&lintLength, sizeof(UnsignedInt32), 1, mpFile) != 1)
00215         throw CCubitFile::eFileReadError;
00216     if(mintSwapEndian)
00217         SwapEndian<UnsignedInt32>(1, &lintLength);
00218     if(lintLength) {
00219         lpachrData = new char[lintLength + 1];
00220         if(!lpachrData)
00221             throw CCubitFile::eMemoryError;
00222         if(fread(lpachrData, sizeof(char), lintLength, mpFile) != lintLength) {
00223             delete[] lpachrData;
00224             throw CCubitFile::eFileReadError;
00225         }   
00226         lpachrData[lintLength] = '\0';
00227         lintMod = (lintLength % sizeof(UnsignedInt32));
00228         if(lintMod) {
00229             lintMod = sizeof(UnsignedInt32) - lintMod;
00230             if(fread(&lachrPad, sizeof(char), lintMod, mpFile) != lintMod) {
00231                 delete[] lpachrData;
00232                 throw CCubitFile::eFileReadError;
00233             }
00234         }
00235     }
00236     return lpachrData;
00237 }
00238 
00239 void CIOWrapper::EndReadBlock()
00240 {
00241     mintBlockStart = mintBlockEnd = 0;
00242 }
00243     
00244 UnsignedInt32 NCubitFile::GetLocation(FILE* f)
00245 {
00246 #ifdef _MSC_VER
00247   // normal ftell() returns long, which is a 32 bit signed integer.
00248   // we use this to increase our 2 GB limit to 4 GB.
00249   // To go past 4GB, we'd have to use a 64 bit integer instead of UnsignedInt32.
00250   __int64 offset = _ftelli64(f);
00251 #else
00252   long offset = ftell(f);
00253 #endif
00254   if(offset == -1L)
00255     throw CCubitFile::eFileTellError;
00256   return static_cast<UnsignedInt32>(offset);
00257 }
00258 
00259 UnsignedInt32 CIOWrapper::GetLocation()
00260 {
00261   return NCubitFile::GetLocation(mpFile);
00262 }
00263 
00264 int NCubitFile::SetLocation(FILE* f, UnsignedInt32 offset, int whence)
00265 {
00266 #ifdef _MSC_VER
00267   return _fseeki64(f, offset, whence);
00268 #else
00269   return fseek(f, offset, whence);
00270 #endif
00271 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines