void CompressWithLZMA2(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf, Byte* ptrProperties) { VectorInStream inStream = { &VectorInStream_Read, &inBuf, 0 }; VectorOutStream outStream = { &VectorOutStream_Write, &outBuf }; CLzma2EncHandle enc; enc = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); assert(enc); CLzma2EncProps props; Lzma2EncProps_Init(&props); //Ivan need change the parameters later //props.lzmaProps.writeEndMark = 1; // 0 or 1 //props.lzmaProps.level = 6; //props.lzmaProps.dictSize = 1 << 14; //props.lzmaProps.numThreads = 8; //props.numTotalThreads = 8; SRes res = Lzma2Enc_SetProps(enc, &props); assert(res == SZ_OK); outBuf.resize(1); // no need outBuf[0] = Lzma2Enc_WriteProperties(enc); *ptrProperties = outBuf[0]; //no need this parameter. UInt64 resLen = inBuf.size(); Byte header[8]; for (int i = 0; i < 8; i++) header[i] = (Byte)(resLen >> (8 * i)); res = Lzma2Enc_Encode(enc, &outStream.SeqOutStream, &inStream.SeqInStream, 0); //res = Lzma2Enc_Encode(enc, (ISeqOutStream*)&outStream, (ISeqInStream*)&inStream, 0); assert(res == SZ_OK); Lzma2Enc_Destroy(enc); FILE *fout = fopen("data.dc.dat", "wb+"); //change the file name. fwrite(&outBuf[0], 1, 1, fout); fwrite(&header[0], 1, 8, fout); fwrite(&outBuf[1], 1, outBuf.size() - 1, fout); fclose(fout); }
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf, ISeqOutStream *outStream, ISeqInStream *inStream, const CXzProps *props, ICompressProgress *progress) { xz->flags = (Byte)props->checkId; RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props)); RINOK(Xz_WriteHeader(xz->flags, outStream)); { CSeqCheckInStream checkInStream; CSeqSizeOutStream seqSizeOutStream; CXzBlock block; int filterIndex = 0; CXzFilter *filter = NULL; const CXzFilterProps *fp = props->filterProps; XzBlock_ClearFlags(&block); XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); if (fp) { filter = &block.filters[filterIndex++]; filter->id = fp->id; filter->propsSize = 0; if (fp->id == XZ_ID_Delta) { filter->props[0] = (Byte)(fp->delta - 1); filter->propsSize = 1; } else if (fp->ipDefined) { SetUi32(filter->props, fp->ip); filter->propsSize = 4; } } { CXzFilter *f = &block.filters[filterIndex++]; f->id = XZ_ID_LZMA2; f->propsSize = 1; f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); } seqSizeOutStream.p.Write = MyWrite; seqSizeOutStream.realStream = outStream; seqSizeOutStream.processed = 0; RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p)); checkInStream.p.Read = SeqCheckInStream_Read; checkInStream.realStream = inStream; SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags)); if (fp) { #ifdef USE_SUBBLOCK if (fp->id == XZ_ID_Subblock) { lzmaf->sb.inStream = &checkInStream.p; RINOK(SbEncInStream_Init(&lzmaf->sb)); } else #endif { lzmaf->filter.realStream = &checkInStream.p; RINOK(SeqInFilter_Init(&lzmaf->filter, filter)); } } { UInt64 packPos = seqSizeOutStream.processed; SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p, fp ? #ifdef USE_SUBBLOCK (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p: #endif &lzmaf->filter.p: &checkInStream.p, progress); RINOK(res); block.unpackSize = checkInStream.processed; block.packSize = seqSizeOutStream.processed - packPos; } { unsigned padSize = 0; Byte buf[128]; while((((unsigned)block.packSize + padSize) & 3) != 0) buf[padSize++] = 0; SeqCheckInStream_GetDigest(&checkInStream, buf + padSize); RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags))); RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc)); } } return Xz_WriteFooter(xz, outStream); }
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf, ISeqOutStream *outStream, ISeqInStream *inStream, const CLzma2EncProps *lzma2Props, Bool useSubblock, ICompressProgress *progress) { xz->flags = XZ_CHECK_CRC32; RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props)); RINOK(Xz_WriteHeader(xz->flags, outStream)); { CSeqCheckInStream checkInStream; CSeqSizeOutStream seqSizeOutStream; CXzBlock block; int filterIndex = 0; XzBlock_ClearFlags(&block); XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0)); if (useSubblock) { CXzFilter *f = &block.filters[filterIndex++]; f->id = XZ_ID_Subblock; f->propsSize = 0; } { CXzFilter *f = &block.filters[filterIndex++]; f->id = XZ_ID_LZMA2; f->propsSize = 1; f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); } seqSizeOutStream.p.Write = MyWrite; seqSizeOutStream.realStream = outStream; seqSizeOutStream.processed = 0; RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p)); checkInStream.p.Read = SeqCheckInStream_Read; checkInStream.realStream = inStream; SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags)); #ifdef USE_SUBBLOCK if (useSubblock) { lzmaf->sb.sb.inStream = &checkInStream.p; SubblockEnc_Init(&lzmaf->sb.sb); } #endif { UInt64 packPos = seqSizeOutStream.processed; SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p, #ifdef USE_SUBBLOCK useSubblock ? &lzmaf->sb.p: #endif &checkInStream.p, progress); RINOK(res); block.unpackSize = checkInStream.processed; block.packSize = seqSizeOutStream.processed - packPos; } { unsigned padSize = 0; Byte buf[128]; while((((unsigned)block.packSize + padSize) & 3) != 0) buf[padSize++] = 0; SeqCheckInStream_GetDigest(&checkInStream, buf + padSize); RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags))); RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc)); } } return Xz_WriteFooter(xz, outStream); }
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) { Byte prop = Lzma2Enc_WriteProperties(_encoder); return WriteStream(outStream, &prop, 1); }
bool ZPatcher::CreatePatchFile(FILE* patchFile, std::string& newVersionPath, PatchFileList_t* patchFileList, ProgressCallback progressFunction, ICompressProgress LZMAProgressCallback) { // Initialize our custom LZMA2 Encoder CLzma2EncHandle hLzma2Enc = InitLzma2Encoder(); fprintf(stdout, "Writing patch data...\n"); Log(LOG, "Writing patch data"); // Write the file header, including our custom LZMA2 props Byte props = Lzma2Enc_WriteProperties(hLzma2Enc); WritePatchFileHeader(patchFile, props); size_t totalFiles = patchFileList->RemovedFileList.size() + patchFileList->AddedFileList.size() + patchFileList->ModifiedFileList.size(); unsigned int i = 0; // Process the removed file list in reverse order - Directories should be the last thing being deleted. for (std::vector<std::string>::reverse_iterator ritr = patchFileList->RemovedFileList.rbegin(); ritr != patchFileList->RemovedFileList.rend(); ++ritr) { // Update our progress bar float progress = ((float)++i / (float)totalFiles) * 100.0f; progressFunction(progress, i, totalFiles); Log(LOG, "[del] %s", ritr->c_str()); WriteFileInfo(patchFile, Patch_File_Delete, ritr->c_str()); } for (std::vector<std::string>::iterator itr = patchFileList->AddedFileList.begin(); itr < patchFileList->AddedFileList.end(); ++itr) { // Update our progress bar float progress = ((float)++i / (float)totalFiles) * 100.0f; progressFunction(progress, i, totalFiles); Log(LOG, "[add] %s", itr->c_str()); size_t fileNameLength = itr->length(); if (fileNameLength > 0 && (*itr)[fileNameLength - 1] != '/') { WriteFileInfo(patchFile, Patch_File_Add, itr->c_str()); std::string localPath = newVersionPath + "/" + *itr; if (!WriteCompressedFile(hLzma2Enc, localPath, patchFile, LZMAProgressCallback)) { return false; } } else { WriteFileInfo(patchFile, Patch_Dir_Add, itr->c_str()); } } // Right now, we replace both the modified files and the added files for (std::vector<std::string>::iterator itr = patchFileList->ModifiedFileList.begin(); itr < patchFileList->ModifiedFileList.end(); ++itr) { // Update our progress bar float progress = ((float)++i / (float)totalFiles) * 100.0f; progressFunction(progress, i, totalFiles); Log(LOG, "[mod] %s", itr->c_str()); WriteFileInfo(patchFile, Patch_File_Replace, itr->c_str()); std::string localPath = newVersionPath + "/" + *itr; if (!WriteCompressedFile(hLzma2Enc, localPath, patchFile, LZMAProgressCallback)) { return false; } } // Update our progress bar float progress = ((float)i / (float)totalFiles) * 100.0f; progressFunction(progress, i, totalFiles); // Hacky hack if we are using our own provided function ;) if (progressFunction == &PrintCreatePatchProgressBar) { fprintf(stdout, "\n"); } Log(LOG, "Patch data writing process completed"); DestroyLzma2EncHandle(hLzma2Enc); return true; }