BinaryInput::BinaryInput( const uint8* data, int64 dataLen, G3DEndian dataEndian, bool compressed, bool copyMemory) { beginEndBits = 0; bitPos = 0; alreadyRead = 0; bufferLength = 0; freeBuffer = copyMemory || compressed; this->fileEndian = dataEndian; this->filename = "<memory>"; pos = 0; swapBytes = needSwapBytes(fileEndian); if (compressed) { // Read the decompressed size from the first 4 bytes length = G3D::readUInt32(data, swapBytes); debugAssert(freeBuffer); buffer = (uint8*)System::malloc(length); unsigned long L = length; // Decompress with zlib int64 result = uncompress(buffer, (unsigned long*)&L, data + 4, dataLen - 4); length = L; bufferLength = L; debugAssert(result == Z_OK); (void)result; } else { length = dataLen; bufferLength = length; if (! copyMemory) { debugAssert(!freeBuffer); buffer = const_cast<uint8*>(data); } else { debugAssert(freeBuffer); buffer = (uint8*)System::malloc(length); System::memcpy(buffer, data, dataLen); } } }
BinaryInput::BinaryInput( const std::string& filename, G3DEndian fileEndian, bool compressed) { alreadyRead = 0; freeBuffer = true; this->fileEndian = fileEndian; this->filename = filename; buffer = NULL; bufferLength = 0; length = 0; pos = 0; beginEndBits = 0; bitPos = 0; // Update global file tracker _internal::currentFilesUsed.append(filename); swapBytes = needSwapBytes(fileEndian); // Figure out how big the file is and verify that it exists. length = fileLength(filename); // Read the file into memory FILE* file = fopen(filename.c_str(), "rb"); if (! file || (length == -1)) { throw format("File not found: \"%s\"", filename.c_str()); return; } if (! compressed && (length > INITIAL_BUFFER_LENGTH)) { // Read only a subset of the file so we don't consume // all available memory. bufferLength = INITIAL_BUFFER_LENGTH; } else { // Either the length is fine or the file is compressed // and requires us to read the whole thing for zlib. bufferLength = length; } debugAssert(freeBuffer); buffer = (uint8*)System::malloc(bufferLength); if (buffer == NULL) { if (compressed) { throw "Not enough memory to load compressed file. (1)"; } // Try to allocate a small array; not much memory is available. // Give up if we can't allocate even 1k. while ((buffer == NULL) && (bufferLength > 1024)) { bufferLength /= 2; buffer = (uint8*)System::malloc(bufferLength); } } debugAssert(buffer); fread(buffer, bufferLength, sizeof(int8), file); fclose(file); file = NULL; pos = 0; if (compressed) { if (bufferLength != length) { throw "Not enough memory to load compressed file. (2)"; } // Decompress // Use the existing buffer as the source, allocate // a new buffer to use as the destination. int64 tempLength = length; length = G3D::readUInt32(buffer, swapBytes); uint8* tempBuffer = buffer; buffer = (uint8*)System::malloc(length); debugAssert(buffer); debugAssert(isValidHeapPointer(tempBuffer)); debugAssert(isValidHeapPointer(buffer)); unsigned long L = length; int64 result = uncompress(buffer, &L, tempBuffer + 4, tempLength - 4); length = L; bufferLength = length; debugAssert(result == Z_OK); (void)result; System::free(tempBuffer); } }
void BinaryInput::setEndian(G3DEndian e) { m_fileEndian = e; m_swapBytes = needSwapBytes(m_fileEndian); }