本文分享一个纯C语言编写的7Z解压缩代码库,本代码库的主要目的是在嵌入式环境下使用7z解压缩文件,可以将升级包通过7z进行压缩,然后发送给设备,减小和设备传输过程中的文件大小,进而达到传输大文件的目的。
下载链接 提取码pi4t
这个库使用的是19版本的库,
这个库是单线程的,移除了多线程代码,因为多线程依赖其他库。我只需要一个独立版本。
已经通过编译。
库的目录结构如下:
#ifdef USE_WINDOWS_FILE
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
{p->handle = CreateFileW(name,writeMode ? GENERIC_WRITE : GENERIC_READ,FILE_SHARE_READ, NULL,writeMode ? CREATE_ALWAYS : OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
}
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
#endifWRes File_Close(CSzFile *p)
{#ifdef USE_WINDOWS_FILEif (p->handle != INVALID_HANDLE_VALUE){if (!CloseHandle(p->handle))return GetLastError();p->handle = INVALID_HANDLE_VALUE;}#elseif (p->file != NULL){int res = fclose(p->file);if (res != 0)return res;p->file = NULL;}#endifreturn 0;
}WRes File_Read(CSzFile *p, void *data, size_t *size)
{size_t originalSize = *size;if (originalSize == 0)return 0;#ifdef USE_WINDOWS_FILE*size = 0;do{DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;DWORD processed = 0;BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);data = (void *)((Byte *)data + processed);originalSize -= processed;*size += processed;if (!res)return GetLastError();if (processed == 0)break;}while (originalSize > 0);return 0;#else*size = fread(data, 1, originalSize, p->file);if (*size == originalSize)return 0;return ferror(p->file);#endif
}
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{CPpmd7 ppmd;CByteInToLook s;SRes res = SZ_OK;s.vt.Read = ReadByte;s.inStream = inStream;s.begin = s.end = s.cur = NULL;s.extra = False;s.res = SZ_OK;s.processed = 0;if (propsSize != 5)return SZ_ERROR_UNSUPPORTED;{unsigned order = props[0];UInt32 memSize = GetUi32(props + 1);if (order < PPMD7_MIN_ORDER ||order > PPMD7_MAX_ORDER ||memSize < PPMD7_MIN_MEM_SIZE ||memSize > PPMD7_MAX_MEM_SIZE)return SZ_ERROR_UNSUPPORTED;Ppmd7_Construct(&ppmd);if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))return SZ_ERROR_MEM;Ppmd7_Init(&ppmd, order);}{CPpmd7z_RangeDec rc;Ppmd7z_RangeDec_CreateVTable(&rc);rc.Stream = &s.vt;if (!Ppmd7z_RangeDec_Init(&rc))res = SZ_ERROR_DATA;else if (s.extra)res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);else{SizeT i;for (i = 0; i < outSize; i++){int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);if (s.extra || sym < 0)break;outBuffer[i] = (Byte)sym;}if (i != outSize)res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))res = SZ_ERROR_DATA;}}Ppmd7_Free(&ppmd, allocMain);return res;
}#endifstatic SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{CLzmaDec state;SRes res = SZ_OK;LzmaDec_Construct(&state);RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));state.dic = outBuffer;state.dicBufSize = outSize;LzmaDec_Init(&state);for (;;){const void *inBuf = NULL;size_t lookahead = (1 << 18);if (lookahead > inSize)lookahead = (size_t)inSize;res = ILookInStream_Look(inStream, &inBuf, &lookahead);if (res != SZ_OK)break;{SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;ELzmaStatus status;res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);lookahead -= inProcessed;inSize -= inProcessed;if (res != SZ_OK)break;if (status == LZMA_STATUS_FINISHED_WITH_MARK){if (outSize != state.dicPos || inSize != 0)res = SZ_ERROR_DATA;break;}if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)break;if (inProcessed == 0 && dicPos == state.dicPos){res = SZ_ERROR_DATA;break;}res = ILookInStream_Skip(inStream, inProcessed);if (res != SZ_OK)break;}}LzmaDec_FreeProbs(&state, allocMain);return res;
}
链接: https://pan.baidu.com/s/1ldjyd3l4zyC9AOw8-ox67g 提取码: pi4t
请用户按需下载