cgma
|
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 }