diff options
Diffstat (limited to 'C/LzmaUtil/LzmaUtil.c')
-rwxr-xr-x | C/LzmaUtil/LzmaUtil.c | 259 |
1 files changed, 101 insertions, 158 deletions
diff --git a/C/LzmaUtil/LzmaUtil.c b/C/LzmaUtil/LzmaUtil.c index a6fa0a2b..016d7b04 100755 --- a/C/LzmaUtil/LzmaUtil.c +++ b/C/LzmaUtil/LzmaUtil.c @@ -1,7 +1,5 @@ /* LzmaUtil.c -- Test application for LZMA compression -2008-08-05 -Igor Pavlov -public domain */ +2008-11-23 : Igor Pavlov : Public domain */ #define _CRT_SECURE_NO_WARNINGS @@ -9,9 +7,11 @@ public domain */ #include <stdlib.h> #include <string.h> +#include "../Alloc.h" +#include "../7zFile.h" +#include "../7zVersion.h" #include "../LzmaDec.h" #include "../LzmaEnc.h" -#include "../Alloc.h" const char *kCantReadMessage = "Can not read input file"; const char *kCantWriteMessage = "Can not write output file"; @@ -19,43 +19,12 @@ const char *kCantAllocateMessage = "Can not allocate memory"; const char *kDataErrorMessage = "Data error"; static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } static ISzAlloc g_Alloc = { SzAlloc, SzFree }; -#define kInBufferSize (1 << 15) -#define kOutBufferSize (1 << 15) - -unsigned char g_InBuffer[kInBufferSize]; -unsigned char g_OutBuffer[kOutBufferSize]; - -size_t MyReadFile(FILE *file, void *data, size_t size) - { return fread(data, 1, size, file); } - -int MyReadFileAndCheck(FILE *file, void *data, size_t size) - { return (MyReadFile(file, data, size) == size); } - -size_t MyWriteFile(FILE *file, const void *data, size_t size) -{ - if (size == 0) - return 0; - return fwrite(data, 1, size, file); -} - -int MyWriteFileAndCheck(FILE *file, const void *data, size_t size) - { return (MyWriteFile(file, data, size) == size); } - -long MyGetFileLength(FILE *file) -{ - long length; - fseek(file, 0, SEEK_END); - length = ftell(file); - fseek(file, 0, SEEK_SET); - return length; -} - void PrintHelp(char *buffer) { - strcat(buffer, "\nLZMA Utility 4.58 Copyright (c) 1999-2008 Igor Pavlov 2008-04-11\n" + strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n" "\nUsage: lzma <e|d> inputFile outputFile\n" " e: encode file\n" " d: decode file\n"); @@ -83,13 +52,65 @@ int PrintUserError(char *buffer) #define IN_BUF_SIZE (1 << 16) #define OUT_BUF_SIZE (1 << 16) -static int Decode(FILE *inFile, FILE *outFile, char *rs) +static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, + UInt64 unpackSize) +{ + int thereIsSize = (unpackSize != (UInt64)(Int64)-1); + Byte inBuf[IN_BUF_SIZE]; + Byte outBuf[OUT_BUF_SIZE]; + size_t inPos = 0, inSize = 0, outPos = 0; + LzmaDec_Init(state); + for (;;) + { + if (inPos == inSize) + { + inSize = IN_BUF_SIZE; + RINOK(inStream->Read(inStream, inBuf, &inSize)); + inPos = 0; + } + { + SRes res; + SizeT inProcessed = inSize - inPos; + SizeT outProcessed = OUT_BUF_SIZE - outPos; + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + ELzmaStatus status; + if (thereIsSize && outProcessed > unpackSize) + { + outProcessed = (SizeT)unpackSize; + finishMode = LZMA_FINISH_END; + } + + res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed, + inBuf + inPos, &inProcessed, finishMode, &status); + inPos += inProcessed; + outPos += outProcessed; + unpackSize -= outProcessed; + + if (outStream) + if (outStream->Write(outStream, outBuf, outPos) != outPos) + return SZ_ERROR_WRITE; + + outPos = 0; + + if (res != SZ_OK || thereIsSize && unpackSize == 0) + return res; + + if (inProcessed == 0 && outProcessed == 0) + { + if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) + return SZ_ERROR_DATA; + return res; + } + } + } +} + +static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream) { UInt64 unpackSize; - int thereIsSize; /* = 1, if there is uncompressed size in headers */ int i; - int res = 0; - + SRes res = 0; + CLzmaDec state; /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ @@ -97,119 +118,31 @@ static int Decode(FILE *inFile, FILE *outFile, char *rs) /* Read and parse header */ - if (!MyReadFileAndCheck(inFile, header, sizeof(header))) - return PrintError(rs, kCantReadMessage); + RINOK(SeqInStream_Read(inStream, header, sizeof(header))); unpackSize = 0; - thereIsSize = 0; for (i = 0; i < 8; i++) - { - unsigned char b = header[LZMA_PROPS_SIZE + i]; - if (b != 0xFF) - thereIsSize = 1; - unpackSize += (UInt64)b << (i * 8); - } + unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8); LzmaDec_Construct(&state); - res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); - if (res != SZ_OK) - return res; - { - Byte inBuf[IN_BUF_SIZE]; - Byte outBuf[OUT_BUF_SIZE]; - size_t inPos = 0, inSize = 0, outPos = 0; - LzmaDec_Init(&state); - for (;;) - { - if (inPos == inSize) - { - inSize = MyReadFile(inFile, inBuf, IN_BUF_SIZE); - inPos = 0; - } - { - SizeT inProcessed = inSize - inPos; - SizeT outProcessed = OUT_BUF_SIZE - outPos; - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - ELzmaStatus status; - if (thereIsSize && outProcessed > unpackSize) - { - outProcessed = (SizeT)unpackSize; - finishMode = LZMA_FINISH_END; - } - - res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed, - inBuf + inPos, &inProcessed, finishMode, &status); - inPos += (UInt32)inProcessed; - outPos += outProcessed; - unpackSize -= outProcessed; - - if (outFile != 0) - MyWriteFile(outFile, outBuf, outPos); - outPos = 0; - - if (res != SZ_OK || thereIsSize && unpackSize == 0) - break; - - if (inProcessed == 0 && outProcessed == 0) - { - if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) - res = SZ_ERROR_DATA; - break; - } - } - } - } - + RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)); + res = Decode2(&state, outStream, inStream, unpackSize); LzmaDec_Free(&state, &g_Alloc); return res; } -typedef struct _CFileSeqInStream -{ - ISeqInStream funcTable; - FILE *file; -} CFileSeqInStream; - -static SRes MyRead(void *p, void *buf, size_t *size) -{ - if (*size == 0) - return SZ_OK; - *size = MyReadFile(((CFileSeqInStream*)p)->file, buf, *size); - /* - if (*size == 0) - return SZE_FAIL; - */ - return SZ_OK; -} - -typedef struct _CFileSeqOutStream -{ - ISeqOutStream funcTable; - FILE *file; -} CFileSeqOutStream; - -static size_t MyWrite(void *pp, const void *buf, size_t size) -{ - return MyWriteFile(((CFileSeqOutStream *)pp)->file, buf, size); -} - -static SRes Encode(FILE *inFile, FILE *outFile, char *rs) +static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs) { CLzmaEncHandle enc; SRes res; - CFileSeqInStream inStream; - CFileSeqOutStream outStream; CLzmaEncProps props; + rs = rs; + enc = LzmaEnc_Create(&g_Alloc); if (enc == 0) return SZ_ERROR_MEM; - inStream.funcTable.Read = MyRead; - inStream.file = inFile; - outStream.funcTable.Write = MyWrite; - outStream.file = outFile; - LzmaEncProps_Init(&props); res = LzmaEnc_SetProps(enc, &props); @@ -217,19 +150,18 @@ static SRes Encode(FILE *inFile, FILE *outFile, char *rs) { Byte header[LZMA_PROPS_SIZE + 8]; size_t headerSize = LZMA_PROPS_SIZE; - UInt64 fileSize; int i; res = LzmaEnc_WriteProperties(enc, header, &headerSize); - fileSize = MyGetFileLength(inFile); for (i = 0; i < 8; i++) header[headerSize++] = (Byte)(fileSize >> (8 * i)); - if (!MyWriteFileAndCheck(outFile, header, headerSize)) - return PrintError(rs, "writing error"); - - if (res == SZ_OK) - res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, - NULL, &g_Alloc, &g_Alloc); + if (outStream->Write(outStream, header, headerSize) != headerSize) + res = SZ_ERROR_WRITE; + else + { + if (res == SZ_OK) + res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc); + } } LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); return res; @@ -237,11 +169,18 @@ static SRes Encode(FILE *inFile, FILE *outFile, char *rs) int main2(int numArgs, const char *args[], char *rs) { - FILE *inFile = 0; - FILE *outFile = 0; + CFileSeqInStream inStream; + CFileOutStream outStream; char c; int res; int encodeMode; + Bool useOutFile = False; + + FileSeqInStream_CreateVTable(&inStream); + File_Construct(&inStream.file); + + FileOutStream_CreateVTable(&outStream); + File_Construct(&outStream.file); if (numArgs == 1) { @@ -261,17 +200,16 @@ int main2(int numArgs, const char *args[], char *rs) size_t t4 = sizeof(UInt32); size_t t8 = sizeof(UInt64); if (t4 != 4 || t8 != 8) - return PrintError(rs, "LZMA UTil needs correct UInt32 and UInt64"); + return PrintError(rs, "Incorrect UInt32 or UInt64"); } - inFile = fopen(args[2], "rb"); - if (inFile == 0) + if (InFile_Open(&inStream.file, args[2]) != 0) return PrintError(rs, "Can not open input file"); if (numArgs > 3) { - outFile = fopen(args[3], "wb+"); - if (outFile == 0) + useOutFile = True; + if (OutFile_Open(&outStream.file, args[3]) != 0) return PrintError(rs, "Can not open output file"); } else if (encodeMode) @@ -279,16 +217,18 @@ int main2(int numArgs, const char *args[], char *rs) if (encodeMode) { - res = Encode(inFile, outFile, rs); + UInt64 fileSize; + File_GetLength(&inStream.file, &fileSize); + res = Encode(&outStream.s, &inStream.s, fileSize, rs); } else { - res = Decode(inFile, outFile, rs); + res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL); } - if (outFile != 0) - fclose(outFile); - fclose(inFile); + if (useOutFile) + File_Close(&outStream.file); + File_Close(&inStream.file); if (res != SZ_OK) { @@ -296,8 +236,11 @@ int main2(int numArgs, const char *args[], char *rs) return PrintError(rs, kCantAllocateMessage); else if (res == SZ_ERROR_DATA) return PrintError(rs, kDataErrorMessage); - else - return PrintErrorNumber(rs, res); + else if (res == SZ_ERROR_WRITE) + return PrintError(rs, kCantWriteMessage); + else if (res == SZ_ERROR_READ) + return PrintError(rs, kCantReadMessage); + return PrintErrorNumber(rs, res); } return 0; } |