void teCompressFile(const teString & from, const teString & to, u32 chunkSize, c8 * chunkInputBuffer, u32 chunkInputBufferSize, c8 * chunkOutputBuffer, u32 chunkOutputBufferSize, u1 highCompression, u1 localPath) { TE_ASSERT(chunkInputBufferSize >= chunkSize); TE_ASSERT(chunkOutputBufferSize >= LZ4_compressBound(chunkSize)); teLZ4CompressionFunction compressionFunction = highCompression ? LZ4_compressHC : LZ4_compress; IBuffer * fileInput = GetFileManager()->OpenFile(from, CFileBuffer::FWM_READ, localPath); if(!fileInput) return; IBuffer * fileOutput = GetFileManager()->OpenFile(to, CFileBuffer::FWM_WRITE, localPath); if(!fileOutput) { TE_SAFE_DROP(fileInput); return; } fileInput->SetStreamMode(true); fileOutput->SetStreamMode(true); fileInput->Lock(BLT_READ); fileInput->SetPosition(0); fileOutput->Lock(BLT_WRITE); fileOutput->SetPosition(0); u32 magicNumber = ARCHIVE_MAGICNUMBER; fileOutput->Write(&magicNumber, ARCHIVE_MAGICNUMBER_SIZE); c8 * inBuffer = chunkInputBuffer; c8 * outBuffer = chunkOutputBuffer; u32 fileSize = 0; while(true) { u32 inSize = teMin(chunkSize, fileInput->GetSize() - fileInput->GetPosition()); fileInput->Read(inBuffer, inSize); fileSize += inSize; if(!inSize) break; u32 outSize = compressionFunction(inBuffer, outBuffer + 4, inSize); *(u32*)outBuffer = outSize; fileOutput->Write(outBuffer, outSize + 4); } fileInput->Unlock(); fileOutput->Unlock(); TE_SAFE_DROP(fileInput); TE_SAFE_DROP(fileOutput); }
void teDecodeFile(const teString & from, const teString & to, u32 chunkSize, c8 * chunkInputBuffer, u32 chunkInputBufferSize, c8 * chunkOutputBuffer, u32 chunkOutputBufferSize, u1 localPath) { TE_ASSERT(chunkInputBufferSize >= LZ4_compressBound(chunkSize)); TE_ASSERT(chunkOutputBufferSize >= chunkSize); IBuffer * fileInput = GetFileManager()->OpenFile(from, CFileBuffer::FWM_READ, localPath); if(!fileInput) return; IBuffer * fileOutput = GetFileManager()->OpenFile(to, CFileBuffer::FWM_WRITE, localPath); if(!fileOutput) { TE_SAFE_DROP(fileInput); return; } fileInput->SetStreamMode(true); fileOutput->SetStreamMode(true); fileInput->Lock(BLT_READ); fileInput->SetPosition(0); u32 magicNumber = u32Max; fileInput->Read(&magicNumber, ARCHIVE_MAGICNUMBER_SIZE); TE_ASSERT(magicNumber == ARCHIVE_MAGICNUMBER); fileOutput->Lock(BLT_WRITE); fileOutput->SetPosition(0); c8 * inBuffer = chunkInputBuffer; c8 * outBuffer = chunkOutputBuffer; while(true) { if((fileInput->GetSize() - fileInput->GetPosition()) < ARCHIVE_MAGICNUMBER_SIZE) break; u32 chunkSizeInFile; fileInput->Read(&chunkSizeInFile, sizeof(u32)); if(chunkSizeInFile == ARCHIVE_MAGICNUMBER) continue; fileInput->Read(inBuffer, chunkSizeInFile); s32 outputSize = LZ4_uncompress_unknownOutputSize(inBuffer, outBuffer, chunkSizeInFile, chunkSize); if(outputSize < 0) { TE_LOG_ERR("lz4 decoding failed, corrupted input\n"); fileInput->Unlock(); fileOutput->Unlock(); TE_SAFE_DROP(fileInput); TE_SAFE_DROP(fileOutput); return; } fileOutput->Write(outBuffer, (u32)outputSize); } fileInput->Unlock(); fileOutput->Unlock(); TE_SAFE_DROP(fileInput); TE_SAFE_DROP(fileOutput); }