| | 1 | |
|---|
| | 2 | #if (defined(WIN32) || defined(WIN64)) && !defined(_WIN32_WCE) |
|---|
| | 3 | |
|---|
| | 4 | #define ODA_NON_TRACING // Comment it to have trace |
|---|
| | 5 | |
|---|
| | 6 | #pragma warning(disable: 4290) |
|---|
| | 7 | |
|---|
| | 8 | #if defined(_MSC_VER) |
|---|
| | 9 | #include <windows.h> |
|---|
| | 10 | #endif |
|---|
| | 11 | |
|---|
| | 12 | #include "OdaCommon.h" |
|---|
| | 13 | #include "OdFileBuf.h" |
|---|
| | 14 | #include "OdString.h" |
|---|
| | 15 | |
|---|
| | 16 | |
|---|
| | 17 | void OdBaseFileBuf::open(const OdString& wszFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 18 | { |
|---|
| | 19 | close(); |
|---|
| | 20 | ODA_TRACE(DD_T("open('%ls', 0x%x, 0x%x, %d)"), wszFileName.c_str(), nDesiredAccess, nShareMode, nCreationDisposition); |
|---|
| | 21 | |
|---|
| | 22 | // Check file name passed |
|---|
| | 23 | if( wszFileName.isEmpty() ) throw OdError(eNoFileName); |
|---|
| | 24 | |
|---|
| | 25 | DWORD dwAccess = 0, dwAttr = 0; |
|---|
| | 26 | if( nDesiredAccess & Oda::kFileRead ) |
|---|
| | 27 | { |
|---|
| | 28 | dwAccess |= GENERIC_READ; |
|---|
| | 29 | dwAttr |= FILE_FLAG_RANDOM_ACCESS; |
|---|
| | 30 | } |
|---|
| | 31 | if( nDesiredAccess & Oda::kFileWrite ) |
|---|
| | 32 | { |
|---|
| | 33 | dwAccess |= GENERIC_WRITE; |
|---|
| | 34 | dwAttr |= FILE_ATTRIBUTE_NORMAL; |
|---|
| | 35 | } |
|---|
| | 36 | |
|---|
| | 37 | DWORD dwShare = 0; |
|---|
| | 38 | if( nShareMode != Oda::kShareDenyRead && nShareMode != Oda::kShareDenyReadWrite ) |
|---|
| | 39 | { |
|---|
| | 40 | dwShare |= FILE_SHARE_READ; |
|---|
| | 41 | } |
|---|
| | 42 | if( nShareMode != Oda::kShareDenyWrite && nShareMode != Oda::kShareDenyReadWrite ) |
|---|
| | 43 | { |
|---|
| | 44 | dwShare |= FILE_SHARE_WRITE; |
|---|
| | 45 | } |
|---|
| | 46 | |
|---|
| | 47 | DWORD dwDisposition = 0; |
|---|
| | 48 | switch( nCreationDisposition ) |
|---|
| | 49 | { |
|---|
| | 50 | case Oda::kCreateNew: |
|---|
| | 51 | dwDisposition = CREATE_NEW; |
|---|
| | 52 | break; |
|---|
| | 53 | case Oda::kCreateAlways: |
|---|
| | 54 | dwDisposition = CREATE_ALWAYS; |
|---|
| | 55 | break; |
|---|
| | 56 | case Oda::kOpenExisting: |
|---|
| | 57 | dwDisposition = OPEN_EXISTING; |
|---|
| | 58 | break; |
|---|
| | 59 | case Oda::kOpenAlways: |
|---|
| | 60 | dwDisposition = OPEN_ALWAYS; |
|---|
| | 61 | break; |
|---|
| | 62 | case Oda::kTruncateExisting: |
|---|
| | 63 | dwDisposition = TRUNCATE_EXISTING; |
|---|
| | 64 | break; |
|---|
| | 65 | } |
|---|
| | 66 | |
|---|
| | 67 | OdString sFileName = wszFileName; |
|---|
| | 68 | m_hFile = ::CreateFileW(wszFileName, dwAccess, dwShare, NULL, dwDisposition, dwAttr, NULL); |
|---|
| | 69 | |
|---|
| | 70 | if( m_hFile == INVALID_HANDLE_VALUE ) |
|---|
| | 71 | { |
|---|
| | 72 | ODA_TRACE1("open() can't open file, GetLastError = %x", ::GetLastError()); |
|---|
| | 73 | throw OdError_FileException(eCantOpenFile, sFileName); |
|---|
| | 74 | } |
|---|
| | 75 | else |
|---|
| | 76 | { |
|---|
| | 77 | m_sFileName = sFileName; |
|---|
| | 78 | m_iFileShare = nShareMode; |
|---|
| | 79 | } |
|---|
| | 80 | |
|---|
| | 81 | //ATLTRACE("OdBaseFileBuf::open(%hs)\n", m_sFileName.c_str()); |
|---|
| | 82 | } |
|---|
| | 83 | |
|---|
| | 84 | void OdBaseFileBuf::close() |
|---|
| | 85 | { |
|---|
| | 86 | if( m_hFile != INVALID_HANDLE_VALUE ) |
|---|
| | 87 | { |
|---|
| | 88 | ODA_TRACE(DD_T("close()")); |
|---|
| | 89 | // Flush buffer if writing was done |
|---|
| | 90 | if( m_bFileWritten ) ::FlushFileBuffers(m_hFile); |
|---|
| | 91 | ::CloseHandle(m_hFile); |
|---|
| | 92 | m_hFile = INVALID_HANDLE_VALUE; |
|---|
| | 93 | } |
|---|
| | 94 | m_sFileName.empty(); |
|---|
| | 95 | m_iFileShare = 0; |
|---|
| | 96 | m_bFileWritten = false; |
|---|
| | 97 | m_bError = false; |
|---|
| | 98 | } |
|---|
| | 99 | |
|---|
| | 100 | OdUInt64 OdBaseFileBuf::length() |
|---|
| | 101 | { |
|---|
| | 102 | ODA_TRACE(DD_T("length()")); |
|---|
| | 103 | return ::GetFileSize(m_hFile, NULL); |
|---|
| | 104 | } |
|---|
| | 105 | |
|---|
| | 106 | #if !defined(INVALID_SET_FILE_POINTER) // for _MSC_VER <= 1200 |
|---|
| | 107 | #define INVALID_SET_FILE_POINTER ((DWORD)-1) |
|---|
| | 108 | #endif |
|---|
| | 109 | |
|---|
| | 110 | OdUInt64 OdBaseFileBuf::seek(OdInt64 offset, OdDb::FilerSeekType whence) |
|---|
| | 111 | { |
|---|
| | 112 | ODA_TRACE(DD_T("seek(%d, %d)"), offset, whence); |
|---|
| | 113 | |
|---|
| | 114 | DWORD dwMethod = 0; |
|---|
| | 115 | switch( whence ) |
|---|
| | 116 | { |
|---|
| | 117 | case OdDb::kSeekFromStart: |
|---|
| | 118 | dwMethod = FILE_BEGIN; |
|---|
| | 119 | break; |
|---|
| | 120 | case OdDb::kSeekFromCurrent: |
|---|
| | 121 | dwMethod = FILE_CURRENT; |
|---|
| | 122 | break; |
|---|
| | 123 | case OdDb::kSeekFromEnd: |
|---|
| | 124 | dwMethod = FILE_END; |
|---|
| | 125 | break; |
|---|
| | 126 | } |
|---|
| | 127 | |
|---|
| | 128 | LARGE_INTEGER li; |
|---|
| | 129 | li.QuadPart = offset; |
|---|
| | 130 | li.LowPart = ::SetFilePointer(m_hFile, li.LowPart, &li.HighPart, dwMethod); |
|---|
| | 131 | if (li.LowPart == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR) |
|---|
| | 132 | { |
|---|
| | 133 | li.QuadPart = -1; |
|---|
| | 134 | throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 135 | } |
|---|
| | 136 | return li.QuadPart; |
|---|
| | 137 | } |
|---|
| | 138 | |
|---|
| | 139 | OdUInt64 OdBaseFileBuf::tell() |
|---|
| | 140 | { |
|---|
| | 141 | ODA_TRACE(DD_T("tell()")); |
|---|
| | 142 | return ::SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); |
|---|
| | 143 | } |
|---|
| | 144 | |
|---|
| | 145 | bool OdBaseFileBuf::isEof() |
|---|
| | 146 | { |
|---|
| | 147 | ODA_TRACE(DD_T("isEof()")); |
|---|
| | 148 | return (::GetFileSize(m_hFile, NULL) == ::SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT)); |
|---|
| | 149 | } |
|---|
| | 150 | |
|---|
| | 151 | OdUInt8 OdBaseFileBuf::getByte() |
|---|
| | 152 | { |
|---|
| | 153 | ODA_TRACE(DD_T("getByte()")); |
|---|
| | 154 | |
|---|
| | 155 | DWORD dwBytes = 0; |
|---|
| | 156 | OdUInt8 b = 0; |
|---|
| | 157 | if( !::ReadFile(m_hFile, &b, 1, &dwBytes, NULL) ) |
|---|
| | 158 | { |
|---|
| | 159 | ODA_TRACE(DD_T("getByte() can't read byte due to read error")); |
|---|
| | 160 | throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 161 | } |
|---|
| | 162 | if( dwBytes == 0 ) |
|---|
| | 163 | { |
|---|
| | 164 | ODA_TRACE(DD_T("getByte() can't read byte due to end-of-file")); |
|---|
| | 165 | throw OdError_FileException(eEndOfFile, m_sFileName); |
|---|
| | 166 | } |
|---|
| | 167 | |
|---|
| | 168 | return b; |
|---|
| | 169 | } |
|---|
| | 170 | |
|---|
| | 171 | void OdBaseFileBuf::getBytes(void* buffer, OdUInt32 nLen) |
|---|
| | 172 | { |
|---|
| | 173 | ODA_TRACE(DD_T("getBytes(%p, %u)"), buffer, nLen); |
|---|
| | 174 | |
|---|
| | 175 | DWORD dwBytes = 0; |
|---|
| | 176 | if( !::ReadFile(m_hFile, buffer, nLen, &dwBytes, NULL) ) |
|---|
| | 177 | { |
|---|
| | 178 | ODA_TRACE(DD_T("getBytes() can't read byte due to read error")); |
|---|
| | 179 | throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 180 | } |
|---|
| | 181 | if( dwBytes < nLen ) |
|---|
| | 182 | { |
|---|
| | 183 | ODA_TRACE(DD_T("getBytes() read only %u bytes due to end-of-file"), dwBytes); |
|---|
| | 184 | throw OdError_FileException(eEndOfFile, m_sFileName); |
|---|
| | 185 | } |
|---|
| | 186 | } |
|---|
| | 187 | |
|---|
| | 188 | void OdBaseFileBuf::putByte(OdUInt8 val) |
|---|
| | 189 | { |
|---|
| | 190 | ODA_TRACE(DD_T("putByte(0x%x)"), val); |
|---|
| | 191 | |
|---|
| | 192 | DWORD dwBytes = 0; |
|---|
| | 193 | BYTE b = val; |
|---|
| | 194 | if( !::WriteFile(m_hFile, &b, 1, &dwBytes, NULL) || dwBytes != 1 ) |
|---|
| | 195 | { |
|---|
| | 196 | ODA_TRACE(DD_T("putByte() can't write byte")); |
|---|
| | 197 | throwOdError(OdError_FileException(eFileWriteError, m_sFileName)); |
|---|
| | 198 | } |
|---|
| | 199 | m_bFileWritten = true; |
|---|
| | 200 | } |
|---|
| | 201 | |
|---|
| | 202 | void OdBaseFileBuf::putBytes(const void* buffer, OdUInt32 nLen) |
|---|
| | 203 | { |
|---|
| | 204 | ODA_TRACE(DD_T("putBytes(%p, %u)"), buffer, nLen); |
|---|
| | 205 | |
|---|
| | 206 | DWORD dwBytes = 0; |
|---|
| | 207 | if( !::WriteFile(m_hFile, buffer, nLen, &dwBytes, NULL) || dwBytes != nLen ) |
|---|
| | 208 | { |
|---|
| | 209 | ODA_TRACE(DD_T("putBytes() can't write bytes")); |
|---|
| | 210 | throwOdError(OdError_FileException(eFileWriteError, m_sFileName)); |
|---|
| | 211 | } |
|---|
| | 212 | m_bFileWritten = true; |
|---|
| | 213 | } |
|---|
| | 214 | |
|---|
| | 215 | void OdBaseFileBuf::truncate() |
|---|
| | 216 | { |
|---|
| | 217 | ODA_TRACE(DD_T("truncate()")); |
|---|
| | 218 | if( !::SetEndOfFile(m_hFile) ) |
|---|
| | 219 | { |
|---|
| | 220 | ODA_TRACE(DD_T("truncate() failed")); |
|---|
| | 221 | throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 222 | } |
|---|
| | 223 | } |
|---|
| | 224 | |
|---|
| | 225 | // Current method behavior description (so required behavior isn't documented in DWGDirect yet): |
|---|
| | 226 | // - Move source stream to nSrcStart position |
|---|
| | 227 | // - Read (nSrcEnd-nSrcStart) bytes from source stream to temporary buffer |
|---|
| | 228 | // - Write buffer to target stream |
|---|
| | 229 | // - Set source stream to nSrcEnd position |
|---|
| | 230 | void OdBaseFileBuf::copyDataTo(OdStreamBuf* pDest, OdUInt64 nSrcStart, OdUInt64 nSrcEnd) |
|---|
| | 231 | { |
|---|
| | 232 | ODA_TRACE(DD_T("copyDataTo(%p, %u, %u)"), pDest, nSrcStart, nSrcEnd); |
|---|
| | 233 | |
|---|
| | 234 | if(nSrcStart==0 && nSrcEnd==0) |
|---|
| | 235 | { |
|---|
| | 236 | nSrcStart = tell(); |
|---|
| | 237 | nSrcEnd = length(); |
|---|
| | 238 | } |
|---|
| | 239 | |
|---|
| | 240 | // Do nothing if incorrect positions passed |
|---|
| | 241 | if( nSrcEnd <= nSrcStart ) return; |
|---|
| | 242 | |
|---|
| | 243 | // Remember current position to restore on error |
|---|
| | 244 | OdUInt64 nPos = tell(); |
|---|
| | 245 | if( nPos != nSrcStart ) |
|---|
| | 246 | { |
|---|
| | 247 | // Move to start position |
|---|
| | 248 | if( seek(nSrcStart, OdDb::kSeekFromStart) != nSrcStart ) |
|---|
| | 249 | { |
|---|
| | 250 | ODA_TRACE(DD_T("copyDataTo() can't move to start position")); |
|---|
| | 251 | throw OdError_FileException(eEndOfFile, m_sFileName); |
|---|
| | 252 | } |
|---|
| | 253 | } |
|---|
| | 254 | |
|---|
| | 255 | // Allocate temporary buffer |
|---|
| | 256 | OdUInt32 nLen = OdUInt32(nSrcEnd - nSrcStart); |
|---|
| | 257 | |
|---|
| | 258 | HLOCAL hBuf = ::LocalAlloc(LHND, nLen); |
|---|
| | 259 | if( hBuf == NULL ) |
|---|
| | 260 | { |
|---|
| | 261 | ODA_TRACE(DD_T("copyDataTo() can't allocate temporary buffer")); |
|---|
| | 262 | seek(nPos, OdDb::kSeekFromStart); |
|---|
| | 263 | throw OdError_FileException(eOutOfMemory, m_sFileName); |
|---|
| | 264 | } |
|---|
| | 265 | |
|---|
| | 266 | void* pBuf = ::LocalLock(hBuf); |
|---|
| | 267 | if( pBuf == NULL ) |
|---|
| | 268 | { |
|---|
| | 269 | ODA_TRACE(DD_T("copyDataTo() can't access to temporary buffer")); |
|---|
| | 270 | ::LocalFree(hBuf); |
|---|
| | 271 | seek(nPos, OdDb::kSeekFromStart); |
|---|
| | 272 | throw OdError_FileException(eOutOfMemory, m_sFileName); |
|---|
| | 273 | } |
|---|
| | 274 | |
|---|
| | 275 | // Read to buffer (current position will be set to nSrcEnd after) |
|---|
| | 276 | getBytes(pBuf, nLen); |
|---|
| | 277 | //seek(nPos, OdDb::kSeekFromStart); |
|---|
| | 278 | |
|---|
| | 279 | // Write to destination |
|---|
| | 280 | pDest->putBytes(pBuf, nLen); |
|---|
| | 281 | |
|---|
| | 282 | ::LocalUnlock(hBuf); |
|---|
| | 283 | ::LocalFree(hBuf); |
|---|
| | 284 | } |
|---|
| | 285 | |
|---|
| | 286 | |
|---|
| | 287 | OdWrFileBuf::OdWrFileBuf() : m_nBufferedSize(0) |
|---|
| | 288 | { |
|---|
| | 289 | } |
|---|
| | 290 | |
|---|
| | 291 | OdWrFileBuf::~OdWrFileBuf() |
|---|
| | 292 | { |
|---|
| | 293 | close(); |
|---|
| | 294 | } |
|---|
| | 295 | |
|---|
| | 296 | #ifndef DD_UNICODE |
|---|
| | 297 | void OdWrFileBuf::open(const OdChar* szFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 298 | { |
|---|
| | 299 | OdWString wsStr = OdStringToWideChar(szFileName); |
|---|
| | 300 | if (wsStr.isEmpty()) |
|---|
| | 301 | throw OdError(eNoFileName); |
|---|
| | 302 | |
|---|
| | 303 | OdBaseFileBuf::open(wsStr.c_str(), nShareMode, nDesiredAccess, nCreationDisposition); |
|---|
| | 304 | } |
|---|
| | 305 | #endif |
|---|
| | 306 | |
|---|
| | 307 | #ifndef DD_UNICODE |
|---|
| | 308 | void OdWrFileBuf::open(const OdCharW* wszFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 309 | #else |
|---|
| | 310 | void OdWrFileBuf::open(const OdString& wszFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 311 | #endif |
|---|
| | 312 | { |
|---|
| | 313 | if (nDesiredAccess == Oda::kFileRead) |
|---|
| | 314 | throw OdError_FileException(eCantOpenFile, m_sFileName); |
|---|
| | 315 | |
|---|
| | 316 | OdBaseFileBuf::open(wszFileName, nShareMode, nDesiredAccess, nCreationDisposition); |
|---|
| | 317 | } |
|---|
| | 318 | |
|---|
| | 319 | #ifndef DD_UNICODE |
|---|
| | 320 | void OdRdFileBuf::open(const OdChar* szFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 321 | { |
|---|
| | 322 | OdWString wsStr = OdStringToWideChar(szFileName); |
|---|
| | 323 | if (wsStr.isEmpty()) |
|---|
| | 324 | throw OdError(eNoFileName); |
|---|
| | 325 | |
|---|
| | 326 | open(wsStr.c_str(), nShareMode, nDesiredAccess, nCreationDisposition); |
|---|
| | 327 | } |
|---|
| | 328 | void OdRdFileBuf::open(const OdCharW* wszFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 329 | #else |
|---|
| | 330 | void OdRdFileBuf::open(const OdString& wszFileName, Oda::FileShareMode nShareMode, Oda::FileAccessMode nDesiredAccess, Oda::FileCreationDisposition nCreationDisposition) |
|---|
| | 331 | #endif |
|---|
| | 332 | { |
|---|
| | 333 | if (nDesiredAccess & Oda::kFileWrite) |
|---|
| | 334 | throw OdError_FileException(eCantOpenFile, m_sFileName); |
|---|
| | 335 | |
|---|
| | 336 | OdBaseFileBuf::open(wszFileName, nShareMode, nDesiredAccess, nCreationDisposition); |
|---|
| | 337 | |
|---|
| | 338 | // Test open mode and file attributes to use fast mapping buffer instead of plain one |
|---|
| | 339 | if( nCreationDisposition == Oda::kOpenExisting || nCreationDisposition == Oda::kOpenAlways ) |
|---|
| | 340 | { |
|---|
| | 341 | // Reject compressed and other special files |
|---|
| | 342 | // TODO Perhaps reject remote files also |
|---|
| | 343 | DWORD dwAttr = |
|---|
| | 344 | #ifdef DD_UNICODE |
|---|
| | 345 | ::GetFileAttributesW(wszFileName); |
|---|
| | 346 | #else |
|---|
| | 347 | ::GetFileAttributesA(OdWideCharToString((LPCWSTR)wszFileName)); |
|---|
| | 348 | #endif //DD_UNICODE |
|---|
| | 349 | if( dwAttr != INVALID_FILE_SIZE/*INVALID_FILE_ATTRIBUTES*/ && |
|---|
| | 350 | !(dwAttr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ENCRYPTED| |
|---|
| | 351 | FILE_ATTRIBUTE_SPARSE_FILE|FILE_ATTRIBUTE_REPARSE_POINT| |
|---|
| | 352 | FILE_ATTRIBUTE_COMPRESSED|FILE_ATTRIBUTE_OFFLINE)) ) |
|---|
| | 353 | { |
|---|
| | 354 | try |
|---|
| | 355 | { |
|---|
| | 356 | // Remember actual file size |
|---|
| | 357 | m_ulSize.LowPart = ::GetFileSize(m_hFile, &m_ulSize.HighPart); |
|---|
| | 358 | |
|---|
| | 359 | DWORD dwProtect = PAGE_READONLY, dwAccess = FILE_MAP_READ; |
|---|
| | 360 | if( nDesiredAccess & Oda::kFileWrite ) |
|---|
| | 361 | { |
|---|
| | 362 | dwProtect = PAGE_READWRITE; |
|---|
| | 363 | dwAccess = FILE_MAP_WRITE; |
|---|
| | 364 | } |
|---|
| | 365 | |
|---|
| | 366 | // Map file into memory |
|---|
| | 367 | m_hFileMap = ::CreateFileMapping(m_hFile, NULL, dwProtect, 0, 0, NULL); |
|---|
| | 368 | if( m_hFileMap == INVALID_HANDLE_VALUE ) throw OdError_FileException(eCantOpenFile, m_sFileName); |
|---|
| | 369 | |
|---|
| | 370 | m_pFileMap = ::MapViewOfFile(m_hFileMap, dwAccess, 0, 0, 0); |
|---|
| | 371 | if( !m_pFileMap ) throw OdError_FileException(eCantOpenFile, m_sFileName); |
|---|
| | 372 | } |
|---|
| | 373 | catch( ... ) |
|---|
| | 374 | { |
|---|
| | 375 | // Fall down to plain buffer use |
|---|
| | 376 | // disable cache |
|---|
| | 377 | } |
|---|
| | 378 | } |
|---|
| | 379 | } |
|---|
| | 380 | } |
|---|
| | 381 | |
|---|
| | 382 | OdRdFileBuf::OdRdFileBuf() |
|---|
| | 383 | { |
|---|
| | 384 | m_hFileMap = INVALID_HANDLE_VALUE; |
|---|
| | 385 | m_pFileMap = NULL; |
|---|
| | 386 | m_ulSize.QuadPart = 0; |
|---|
| | 387 | m_ulPos.QuadPart = 0; |
|---|
| | 388 | } |
|---|
| | 389 | |
|---|
| | 390 | void OdRdFileBuf::close() |
|---|
| | 391 | { |
|---|
| | 392 | if( m_pFileMap ) |
|---|
| | 393 | { |
|---|
| | 394 | ::UnmapViewOfFile(m_pFileMap); |
|---|
| | 395 | m_pFileMap = NULL; |
|---|
| | 396 | } |
|---|
| | 397 | if( m_hFileMap != INVALID_HANDLE_VALUE ) |
|---|
| | 398 | { |
|---|
| | 399 | ::CloseHandle(m_hFileMap); |
|---|
| | 400 | m_hFileMap = INVALID_HANDLE_VALUE; |
|---|
| | 401 | } |
|---|
| | 402 | m_ulSize.QuadPart = 0; |
|---|
| | 403 | m_ulPos.QuadPart = 0; |
|---|
| | 404 | |
|---|
| | 405 | OdBaseFileBuf::close(); |
|---|
| | 406 | } |
|---|
| | 407 | |
|---|
| | 408 | OdUInt64 OdRdFileBuf::length() |
|---|
| | 409 | { |
|---|
| | 410 | return memBufferUsed() ? OdUInt64(m_ulSize.QuadPart) : OdBaseFileBuf::length(); |
|---|
| | 411 | } |
|---|
| | 412 | |
|---|
| | 413 | OdUInt64 OdRdFileBuf::seek(OdInt64 offset, OdDb::FilerSeekType whence) |
|---|
| | 414 | { |
|---|
| | 415 | if (!memBufferUsed()) |
|---|
| | 416 | return OdBaseFileBuf::seek(offset, whence); |
|---|
| | 417 | |
|---|
| | 418 | switch( whence ) |
|---|
| | 419 | { |
|---|
| | 420 | case OdDb::kSeekFromStart: |
|---|
| | 421 | if( offset < 0 || offset > (OdInt64)m_ulSize.QuadPart ) throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 422 | m_ulPos.QuadPart = offset; |
|---|
| | 423 | break; |
|---|
| | 424 | case OdDb::kSeekFromCurrent: |
|---|
| | 425 | if( (m_ulPos.QuadPart + offset) < 0 || (m_ulPos.QuadPart + offset) > m_ulSize.QuadPart ) throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 426 | m_ulPos.QuadPart += offset; |
|---|
| | 427 | break; |
|---|
| | 428 | case OdDb::kSeekFromEnd: |
|---|
| | 429 | if( offset > 0 || -offset > (OdInt64)m_ulSize.QuadPart ) throw OdError_FileException(eFileInternalErr, m_sFileName); |
|---|
| | 430 | m_ulPos.QuadPart = m_ulSize.QuadPart + offset; |
|---|
| | 431 | break; |
|---|
| | 432 | } |
|---|
| | 433 | |
|---|
| | 434 | return m_ulPos.QuadPart; |
|---|
| | 435 | } |
|---|
| | 436 | |
|---|
| | 437 | OdUInt64 OdRdFileBuf::tell() |
|---|
| | 438 | { |
|---|
| | 439 | if (!memBufferUsed()) |
|---|
| | 440 | return OdBaseFileBuf::tell(); |
|---|
| | 441 | |
|---|
| | 442 | return OdUInt64(m_ulPos.QuadPart); |
|---|
| | 443 | } |
|---|
| | 444 | |
|---|
| | 445 | bool OdRdFileBuf::isEof() |
|---|
| | 446 | { |
|---|
| | 447 | if (!memBufferUsed()) |
|---|
| | 448 | return OdBaseFileBuf::isEof(); |
|---|
| | 449 | |
|---|
| | 450 | return (m_ulPos.QuadPart == m_ulSize.QuadPart); |
|---|
| | 451 | } |
|---|
| | 452 | |
|---|
| | 453 | OdUInt8 OdRdFileBuf::getByte() |
|---|
| | 454 | { |
|---|
| | 455 | if (!memBufferUsed()) |
|---|
| | 456 | return OdBaseFileBuf::getByte(); |
|---|
| | 457 | |
|---|
| | 458 | if( m_ulPos.QuadPart >= m_ulSize.QuadPart ) throw OdError_FileException(eEndOfFile, m_sFileName); |
|---|
| | 459 | |
|---|
| | 460 | return ((OdUInt8*)m_pFileMap)[m_ulPos.QuadPart++]; |
|---|
| | 461 | } |
|---|
| | 462 | |
|---|
| | 463 | void OdRdFileBuf::getBytes(void* buffer, OdUInt32 nLen) |
|---|
| | 464 | { |
|---|
| | 465 | if (!memBufferUsed()) |
|---|
| | 466 | { |
|---|
| | 467 | OdBaseFileBuf::getBytes(buffer, nLen); |
|---|
| | 468 | return; |
|---|
| | 469 | } |
|---|
| | 470 | |
|---|
| | 471 | if( (m_ulPos.QuadPart + nLen) > m_ulSize.QuadPart ) throw OdError_FileException(eEndOfFile, m_sFileName); |
|---|
| | 472 | |
|---|
| | 473 | ::CopyMemory(buffer, ((OdUInt8*)m_pFileMap) + m_ulPos.QuadPart, nLen); |
|---|
| | 474 | |
|---|
| | 475 | m_ulPos.QuadPart += nLen; |
|---|
| | 476 | } |
|---|
| | 477 | |
|---|
| | 478 | void OdRdFileBuf::putByte(OdUInt8 val) |
|---|
| | 479 | { |
|---|
| | 480 | if (!memBufferUsed()) |
|---|
| | 481 | { |
|---|
| | 482 | OdBaseFileBuf::putByte(val); |
|---|
| | 483 | return; |
|---|
| | 484 | } |
|---|
| | 485 | |
|---|
| | 486 | if( m_ulPos.QuadPart > m_ulSize.QuadPart ) throw OdError_FileException(eFileWriteError, m_sFileName); |
|---|
| | 487 | |
|---|
| | 488 | ((OdUInt8*)m_pFileMap)[m_ulPos.QuadPart++] = val; |
|---|
| | 489 | |
|---|
| | 490 | // TODO? m_bFileWritten = true; |
|---|
| | 491 | } |
|---|
| | 492 | |
|---|
| | 493 | void OdRdFileBuf::putBytes(const void* buffer, OdUInt32 nLen) |
|---|
| | 494 | { |
|---|
| | 495 | if (!memBufferUsed()) |
|---|
| | 496 | { |
|---|
| | 497 | OdBaseFileBuf::putBytes(buffer, nLen); |
|---|
| | 498 | return; |
|---|
| | 499 | } |
|---|
| | 500 | |
|---|
| | 501 | if( (m_ulPos.QuadPart + nLen) > m_ulSize.QuadPart ) throw OdError_FileException(eFileWriteError, m_sFileName); |
|---|
| | 502 | |
|---|
| | 503 | ::CopyMemory(((OdUInt8*)m_pFileMap) + m_ulPos.QuadPart, buffer, nLen); |
|---|
| | 504 | |
|---|
| | 505 | m_ulPos.QuadPart += nLen; |
|---|
| | 506 | |
|---|
| | 507 | // TODO? m_bFileWritten = true; |
|---|
| | 508 | } |
|---|
| | 509 | |
|---|
| | 510 | void OdRdFileBuf::truncate() |
|---|
| | 511 | { |
|---|
| | 512 | if (!memBufferUsed()) |
|---|
| | 513 | { |
|---|
| | 514 | OdBaseFileBuf::truncate(); |
|---|
| | 515 | return; |
|---|
| | 516 | } |
|---|
| | 517 | |
|---|
| | 518 | throw OdError_FileException(eFileWriteError, m_sFileName); |
|---|
| | 519 | } |
|---|
| | 520 | |
|---|
| | 521 | // Current method behavior description (so required behavior isn't documented in DWGDirect yet): |
|---|
| | 522 | // - Move source stream to nSrcStart position |
|---|
| | 523 | // - Read (nSrcEnd-nSrcStart) bytes from source stream to temporary buffer |
|---|
| | 524 | // - Write buffer to target stream |
|---|
| | 525 | // - Set source stream to nSrcEnd position |
|---|
| | 526 | void OdRdFileBuf::copyDataTo(OdStreamBuf* pDest, OdUInt64 nSrcStart, OdUInt64 nSrcEnd) |
|---|
| | 527 | { |
|---|
| | 528 | if (!memBufferUsed()) |
|---|
| | 529 | { |
|---|
| | 530 | OdBaseFileBuf::copyDataTo(pDest, nSrcStart, nSrcEnd); |
|---|
| | 531 | return; |
|---|
| | 532 | } |
|---|
| | 533 | |
|---|
| | 534 | if( !pDest ) throw OdError_FileException(eNullObjectPointer, m_sFileName); |
|---|
| | 535 | |
|---|
| | 536 | if(nSrcStart==0 && nSrcEnd==0) |
|---|
| | 537 | { |
|---|
| | 538 | nSrcStart = tell(); |
|---|
| | 539 | nSrcEnd = length(); |
|---|
| | 540 | } |
|---|
| | 541 | |
|---|
| | 542 | // Do nothing if incorrect positions passed |
|---|
| | 543 | if( nSrcEnd <= nSrcStart ) return; |
|---|
| | 544 | |
|---|
| | 545 | if( nSrcEnd > m_ulSize.QuadPart ) throw OdError_FileException(eEndOfFile, m_sFileName); |
|---|
| | 546 | |
|---|
| | 547 | pDest->putBytes(((OdUInt8*)m_pFileMap) + nSrcStart, OdUInt32(nSrcEnd - nSrcStart)); |
|---|
| | 548 | } |
|---|
| | 549 | |
|---|
| | 550 | OdUInt64 OdWrFileBuf::seek(OdInt64 offset, OdDb::FilerSeekType whence) |
|---|
| | 551 | { |
|---|
| | 552 | flush(); |
|---|
| | 553 | return OdBaseFileBuf::seek(offset, whence); |
|---|
| | 554 | } |
|---|
| | 555 | |
|---|
| | 556 | void OdWrFileBuf::putByte(OdUInt8 val) |
|---|
| | 557 | { |
|---|
| | 558 | if ( m_nBufferedSize == WRITING_BUFFER_LENGTH ) |
|---|
| | 559 | { |
|---|
| | 560 | flush(); |
|---|
| | 561 | } |
|---|
| | 562 | m_pBuffer[m_nBufferedSize++] = val; |
|---|
| | 563 | } |
|---|
| | 564 | |
|---|
| | 565 | void OdWrFileBuf::putBytes(const void* buffer, OdUInt32 nLen) |
|---|
| | 566 | { |
|---|
| | 567 | if (nLen > WRITING_BUFFER_LENGTH) |
|---|
| | 568 | { |
|---|
| | 569 | flush(); |
|---|
| | 570 | OdBaseFileBuf::putBytes(buffer, nLen); |
|---|
| | 571 | return; |
|---|
| | 572 | } |
|---|
| | 573 | if ( m_nBufferedSize + nLen > WRITING_BUFFER_LENGTH ) |
|---|
| | 574 | { |
|---|
| | 575 | flush(); |
|---|
| | 576 | } |
|---|
| | 577 | memcpy(m_pBuffer + m_nBufferedSize, buffer, nLen); |
|---|
| | 578 | m_nBufferedSize += nLen; |
|---|
| | 579 | } |
|---|
| | 580 | |
|---|
| | 581 | OdUInt64 OdWrFileBuf::tell() |
|---|
| | 582 | { |
|---|
| | 583 | return OdBaseFileBuf::tell() + m_nBufferedSize; |
|---|
| | 584 | } |
|---|
| | 585 | |
|---|
| | 586 | void OdWrFileBuf::close() |
|---|
| | 587 | { |
|---|
| | 588 | if (!errorModeEnabled()) |
|---|
| | 589 | // to prevent second exception in putBytes. cr 3861 |
|---|
| | 590 | { |
|---|
| | 591 | flush(); |
|---|
| | 592 | } |
|---|
| | 593 | OdBaseFileBuf::close(); |
|---|
| | 594 | } |
|---|
| | 595 | |
|---|
| | 596 | OdUInt8 OdWrFileBuf::getByte() |
|---|
| | 597 | { |
|---|
| | 598 | flush(); |
|---|
| | 599 | return OdBaseFileBuf::getByte(); |
|---|
| | 600 | } |
|---|
| | 601 | void OdWrFileBuf::getBytes(void* buffer, OdUInt32 nLen) |
|---|
| | 602 | { |
|---|
| | 603 | flush(); |
|---|
| | 604 | OdBaseFileBuf::getBytes(buffer,nLen); |
|---|
| | 605 | } |
|---|
| | 606 | void OdWrFileBuf::copyDataTo(OdStreamBuf* pDest, OdUInt64 nSrcStart, OdUInt64 nSrcEnd) |
|---|
| | 607 | { |
|---|
| | 608 | flush(); |
|---|
| | 609 | OdBaseFileBuf::copyDataTo(pDest, nSrcStart,nSrcEnd); |
|---|
| | 610 | } |
|---|
| | 611 | |
|---|
| | 612 | OdUInt64 OdWrFileBuf::length() |
|---|
| | 613 | { |
|---|
| | 614 | OdUInt64 l = OdBaseFileBuf::length(); |
|---|
| | 615 | OdUInt64 pos = OdBaseFileBuf::tell(); |
|---|
| | 616 | if ( pos + m_nBufferedSize > l ) |
|---|
| | 617 | { |
|---|
| | 618 | return pos + m_nBufferedSize; |
|---|
| | 619 | } |
|---|
| | 620 | else |
|---|
| | 621 | { |
|---|
| | 622 | return l; |
|---|
| | 623 | } |
|---|
| | 624 | } |
|---|
| | 625 | |
|---|
| | 626 | #else // #ifdef WIN32 |
|---|
| | 627 | |
|---|