diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2008-11-23 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:57 +0300 |
commit | b717a4dbfe15fd7540e68e6c5ccbe91901bbadba (patch) | |
tree | c89b25a1f9a690e69cd20e313be9eb4180ee7a6f /C | |
parent | c10e6b16f6d5484ed896b2c614cb7fb77f336d24 (diff) |
4.61 beta
Diffstat (limited to 'C')
47 files changed, 1079 insertions, 875 deletions
@@ -1,7 +1,5 @@ /* 7zBuf.h -- Byte Buffer -2008-05-01 -Igor Pavlov -Public domain */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __7Z_BUF_H #define __7Z_BUF_H @@ -18,4 +16,16 @@ void Buf_Init(CBuf *p); int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); void Buf_Free(CBuf *p, ISzAlloc *alloc); +typedef struct +{ + Byte *data; + size_t size; + size_t pos; +} CDynBuf; + +void DynBuf_Construct(CDynBuf *p); +void DynBuf_SeekToBeg(CDynBuf *p); +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); +void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); + #endif diff --git a/C/7zBuf2.c b/C/7zBuf2.c new file mode 100755 index 00000000..8d17e0dc --- /dev/null +++ b/C/7zBuf2.c @@ -0,0 +1,45 @@ +/* 7zBuf2.c -- Byte Buffer +2008-10-04 : Igor Pavlov : Public domain */ + +#include <string.h> +#include "7zBuf.h" + +void DynBuf_Construct(CDynBuf *p) +{ + p->data = 0; + p->size = 0; + p->pos = 0; +} + +void DynBuf_SeekToBeg(CDynBuf *p) +{ + p->pos = 0; +} + +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) +{ + if (size > p->size - p->pos) + { + size_t newSize = p->pos + size; + Byte *data; + newSize += newSize / 4; + data = (Byte *)alloc->Alloc(alloc, newSize); + if (data == 0) + return 0; + p->size = newSize; + memcpy(data, p->data, p->pos); + alloc->Free(alloc, p->data); + p->data = data; + } + memcpy(p->data + p->pos, buf, size); + p->pos += size; + return 1; +} + +void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->data); + p->data = 0; + p->size = 0; + p->pos = 0; +} diff --git a/C/7zFile.c b/C/7zFile.c new file mode 100755 index 00000000..9a44c59a --- /dev/null +++ b/C/7zFile.c @@ -0,0 +1,263 @@ +/* 7zFile.c -- File IO +2008-11-22 : Igor Pavlov : Public domain */ + +#include "7zFile.h" + +#ifndef USE_WINDOWS_FILE + +#include <errno.h> + +#endif + +#ifdef USE_WINDOWS_FILE + +/* + ReadFile and WriteFile functions in Windows have BUG: + If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) + from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES + (Insufficient system resources exist to complete the requested service). + Probably in some version of Windows there are problems with other sizes: + for 32 MB (maybe also for 16 MB). + And message can be "Network connection was lost" +*/ + +#define kChunkSizeMax (1 << 22) + +#endif + +void File_Construct(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + p->handle = INVALID_HANDLE_VALUE; + #else + p->file = NULL; + #endif +} + +static WRes File_Open(CSzFile *p, const char *name, int writeMode) +{ + #ifdef USE_WINDOWS_FILE + p->handle = CreateFileA(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(); + #else + p->file = fopen(name, writeMode ? "wb+" : "rb"); + return (p->file != 0) ? 0 : errno; + #endif +} + +WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } +WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } + +WRes File_Close(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + if (p->handle != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(p->handle)) + return GetLastError(); + p->handle = INVALID_HANDLE_VALUE; + } + #else + if (p->file != NULL) + { + int res = fclose(p->file); + if (res != 0) + return res; + p->file = NULL; + } + #endif + return 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 +} + +WRes File_Write(CSzFile *p, const 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 = WriteFile(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 = fwrite(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + + #endif +} + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) +{ + #ifdef USE_WINDOWS_FILE + + LARGE_INTEGER value; + DWORD moveMethod; + value.LowPart = (DWORD)*pos; + value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ + switch (origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return ERROR_INVALID_PARAMETER; + } + value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + { + WRes res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *pos = ((Int64)value.HighPart << 32) | value.LowPart; + return 0; + + #else + + int moveMethod; + int res; + switch (origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return 1; + } + res = fseek(p->file, (long)*pos, moveMethod); + *pos = ftell(p->file); + return res; + + #endif +} + +WRes File_GetLength(CSzFile *p, UInt64 *length) +{ + #ifdef USE_WINDOWS_FILE + + DWORD sizeHigh; + DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + { + DWORD res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *length = (((UInt64)sizeHigh) << 32) + sizeLow; + return 0; + + #else + + long pos = ftell(p->file); + int res = fseek(p->file, 0, SEEK_END); + *length = ftell(p->file); + fseek(p->file, pos, SEEK_SET); + return res; + + #endif +} + + +/* ---------- FileSeqInStream ---------- */ + +static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) +{ + CFileSeqInStream *p = (CFileSeqInStream *)pp; + return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; +} + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p) +{ + p->s.Read = FileSeqInStream_Read; +} + + +/* ---------- FileInStream ---------- */ + +static SRes FileInStream_Read(void *pp, void *buf, size_t *size) +{ + CFileInStream *p = (CFileInStream *)pp; + return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) +{ + CFileInStream *p = (CFileInStream *)pp; + return File_Seek(&p->file, pos, origin); +} + +void FileInStream_CreateVTable(CFileInStream *p) +{ + p->s.Read = FileInStream_Read; + p->s.Seek = FileInStream_Seek; +} + + +/* ---------- FileOutStream ---------- */ + +static size_t FileOutStream_Write(void *pp, const void *data, size_t size) +{ + CFileOutStream *p = (CFileOutStream *)pp; + File_Write(&p->file, data, &size); + return size; +} + +void FileOutStream_CreateVTable(CFileOutStream *p) +{ + p->s.Write = FileOutStream_Write; +} diff --git a/C/7zFile.h b/C/7zFile.h new file mode 100755 index 00000000..fbef6837 --- /dev/null +++ b/C/7zFile.h @@ -0,0 +1,74 @@ +/* 7zFile.h -- File IO +2008-11-22 : Igor Pavlov : Public domain */ + +#ifndef __7Z_FILE_H +#define __7Z_FILE_H + +#ifdef _WIN32 +#define USE_WINDOWS_FILE +#endif + +#ifdef USE_WINDOWS_FILE +#include <windows.h> +#else +#include <stdio.h> +#endif + +#include "Types.h" + + +/* ---------- File ---------- */ + +typedef struct +{ + #ifdef USE_WINDOWS_FILE + HANDLE handle; + #else + FILE *file; + #endif +} CSzFile; + +void File_Construct(CSzFile *p); +WRes InFile_Open(CSzFile *p, const char *name); +WRes OutFile_Open(CSzFile *p, const char *name); +WRes File_Close(CSzFile *p); + +/* reads max(*size, remain file's size) bytes */ +WRes File_Read(CSzFile *p, void *data, size_t *size); + +/* writes *size bytes */ +WRes File_Write(CSzFile *p, const void *data, size_t *size); + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); +WRes File_GetLength(CSzFile *p, UInt64 *length); + + +/* ---------- FileInStream ---------- */ + +typedef struct +{ + ISeqInStream s; + CSzFile file; +} CFileSeqInStream; + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p); + + +typedef struct +{ + ISeekInStream s; + CSzFile file; +} CFileInStream; + +void FileInStream_CreateVTable(CFileInStream *p); + + +typedef struct +{ + ISeqOutStream s; + CSzFile file; +} CFileOutStream; + +void FileOutStream_CreateVTable(CFileOutStream *p); + +#endif diff --git a/C/7zStream.c b/C/7zStream.c new file mode 100755 index 00000000..86232aa3 --- /dev/null +++ b/C/7zStream.c @@ -0,0 +1,169 @@ +/* 7zStream.c -- 7z Stream functions +2008-11-23 : Igor Pavlov : Public domain */ + +#include <string.h> + +#include "Types.h" + +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(stream->Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) +{ + return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) +{ + size_t processed = 1; + RINOK(stream->Read(stream, buf, &processed)); + return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; +} + +SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) +{ + Int64 t = offset; + return stream->Seek(stream, &t, SZ_SEEK_SET); +} + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) +{ + void *lookBuf; + if (*size == 0) + return SZ_OK; + RINOK(stream->Look(stream, &lookBuf, size)); + memcpy(buf, lookBuf, *size); + return stream->Skip(stream, *size); +} + +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(stream->Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) +{ + return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) +{ + SRes res = SZ_OK; + CLookToRead *p = (CLookToRead *)pp; + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size > 0) + { + p->pos = 0; + size2 = LookToRead_BUF_SIZE; + res = p->realStream->Read(p->realStream, p->buf, &size2); + p->size = size2; + } + if (size2 < *size) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) +{ + SRes res = SZ_OK; + CLookToRead *p = (CLookToRead *)pp; + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size > 0) + { + p->pos = 0; + if (*size > LookToRead_BUF_SIZE) + *size = LookToRead_BUF_SIZE; + res = p->realStream->Read(p->realStream, p->buf, size); + size2 = p->size = *size; + } + if (size2 < *size) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead_Skip(void *pp, size_t offset) +{ + CLookToRead *p = (CLookToRead *)pp; + p->pos += offset; + return SZ_OK; +} + +static SRes LookToRead_Read(void *pp, void *buf, size_t *size) +{ + CLookToRead *p = (CLookToRead *)pp; + size_t rem = p->size - p->pos; + if (rem == 0) + return p->realStream->Read(p->realStream, buf, size); + if (rem > *size) + rem = *size; + memcpy(buf, p->buf + p->pos, rem); + p->pos += rem; + *size = rem; + return SZ_OK; +} + +static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) +{ + CLookToRead *p = (CLookToRead *)pp; + p->pos = p->size = 0; + return p->realStream->Seek(p->realStream, pos, origin); +} + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead) +{ + p->s.Look = lookahead ? + LookToRead_Look_Lookahead : + LookToRead_Look_Exact; + p->s.Skip = LookToRead_Skip; + p->s.Read = LookToRead_Read; + p->s.Seek = LookToRead_Seek; +} + +void LookToRead_Init(CLookToRead *p) +{ + p->pos = p->size = 0; +} + +static SRes SecToLook_Read(void *pp, void *buf, size_t *size) +{ + CSecToLook *p = (CSecToLook *)pp; + return LookInStream_LookRead(p->realStream, buf, size); +} + +void SecToLook_CreateVTable(CSecToLook *p) +{ + p->s.Read = SecToLook_Read; +} + +static SRes SecToRead_Read(void *pp, void *buf, size_t *size) +{ + CSecToRead *p = (CSecToRead *)pp; + return p->realStream->Read(p->realStream, buf, size); +} + +void SecToRead_CreateVTable(CSecToRead *p) +{ + p->s.Read = SecToRead_Read; +} diff --git a/C/7zVersion.h b/C/7zVersion.h new file mode 100755 index 00000000..18de3e85 --- /dev/null +++ b/C/7zVersion.h @@ -0,0 +1,7 @@ +#define MY_VER_MAJOR 4 +#define MY_VER_MINOR 61 +#define MY_VER_BUILD 0 +#define MY_VERSION "4.61 beta" +#define MY_DATE "2008-10-28" +#define MY_COPYRIGHT ": Igor Pavlov : Public domain" +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE @@ -1,5 +1,5 @@ /* Alloc.c -- Memory allocation functions -2008-08-05 +2008-09-24 Igor Pavlov Public domain */ @@ -25,16 +25,21 @@ void *MyAlloc(size_t size) if (size == 0) return 0; #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++); - #endif + { + void *p = malloc(size); + fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); + return p; + } + #else return malloc(size); + #endif } void MyFree(void *address) { #ifdef _SZ_ALLOC_DEBUG if (address != 0) - fprintf(stderr, "\nFree; count = %10d", --g_allocCount); + fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); #endif free(address); } diff --git a/C/Archive/7z/7z.dsp b/C/Archive/7z/7z.dsp index a0246af9..9626b03e 100755 --- a/C/Archive/7z/7z.dsp +++ b/C/Archive/7z/7z.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FAs /YX /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /YX /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -104,6 +104,18 @@ SOURCE=..\..\7zCrc.h # End Source File # Begin Source File +SOURCE=..\..\7zFile.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zStream.c +# End Source File +# Begin Source File + SOURCE=..\..\Bcj2.c # End Source File # Begin Source File diff --git a/C/Archive/7z/7zAlloc.c b/C/Archive/7z/7zAlloc.c index 1b48a258..4bfaf42a 100755 --- a/C/Archive/7z/7zAlloc.c +++ b/C/Archive/7z/7zAlloc.c @@ -1,7 +1,5 @@ /* 7zAlloc.c -- Allocation functions -2008-03-28 -Igor Pavlov -Public domain */ +2008-10-04 : Igor Pavlov : Public domain */ #include <stdlib.h> #include "7zAlloc.h" diff --git a/C/Archive/7z/7zAlloc.h b/C/Archive/7z/7zAlloc.h index 714ecf15..e752ef18 100755 --- a/C/Archive/7z/7zAlloc.h +++ b/C/Archive/7z/7zAlloc.h @@ -1,7 +1,5 @@ /* 7zAlloc.h -- Allocation functions -2008-03-28 -Igor Pavlov -Public domain */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __7Z_ALLOC_H #define __7Z_ALLOC_H diff --git a/C/Archive/7z/7zDecode.c b/C/Archive/7z/7zDecode.c index aad7daf8..02526f0e 100755 --- a/C/Archive/7z/7zDecode.c +++ b/C/Archive/7z/7zDecode.c @@ -1,32 +1,23 @@ -/* 7zDecode.c Decoding from 7z folder -2008-08-05 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zDecode.h for license options */ +/* 7zDecode.c -- Decoding from 7z folder +2008-11-23 : Igor Pavlov : Public domain */ #include <string.h> -#include "7zDecode.h" -#include "../../LzmaDec.h" -#include "../../Bra.h" #include "../../Bcj2.h" +#include "../../Bra.h" +#include "../../LzmaDec.h" +#include "7zDecode.h" #define k_Copy 0 #define k_LZMA 0x30101 #define k_BCJ 0x03030103 #define k_BCJ2 0x0303011B -/* -#ifdef _LZMA_IN_CB -*/ - -static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inStream, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) +static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) { CLzmaDec state; - int res = SZ_OK; - size_t _inSize; - Byte *inBuf = NULL; + SRes res = SZ_OK; LzmaDec_Construct(&state); RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); @@ -34,65 +25,60 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inS state.dicBufSize = outSize; LzmaDec_Init(&state); - _inSize = 0; - for (;;) { - if (_inSize == 0) - { - _inSize = (1 << 18); - if (_inSize > inSize) - _inSize = (size_t)(inSize); - res = inStream->Read((void *)inStream, (void **)&inBuf, &_inSize); - if (res != SZ_OK) - break; - inSize -= _inSize; - } + Byte *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; { - SizeT inProcessed = _inSize, dicPos = state.dicPos; + SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; ELzmaStatus status; res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - _inSize -= inProcessed; - inBuf = (Byte *)inBuf + inProcessed; + lookahead -= inProcessed; + inSize -= inProcessed; if (res != SZ_OK) break; if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) { - if (state.dicBufSize != outSize || _inSize != 0 || + if (state.dicBufSize != outSize || lookahead != 0 || (status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) res = SZ_ERROR_DATA; break; } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; } } LzmaDec_FreeProbs(&state, allocMain); - return res; } -static SRes SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer) +static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) { while (inSize > 0) { - void *inBuffer; + void *inBuf; size_t curSize = (1 << 18); if (curSize > inSize) - curSize = (size_t)(inSize); - RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, &curSize)); + curSize = (size_t)inSize; + RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); if (curSize == 0) return SZ_ERROR_INPUT_EOF; - memcpy(outBuffer, inBuffer, curSize); + memcpy(outBuffer, inBuf, curSize); outBuffer += curSize; inSize -= curSize; + RINOK(inStream->Skip((void *)inStream, curSize)); } return SZ_OK; } -/* -#endif -*/ #define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) #define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) @@ -141,31 +127,23 @@ SRes CheckSupportedFolder(const CSzFolder *f) return SZ_ERROR_UNSUPPORTED; } -CFileSize GetSum(const CFileSize *values, UInt32 index) +UInt64 GetSum(const UInt64 *values, UInt32 index) { - CFileSize sum = 0; + UInt64 sum = 0; UInt32 i; for (i = 0; i < index; i++) sum += values[i]; return sum; } -SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, - /* - #ifdef _LZMA_IN_CB - */ - ISzInStream *inStream, CFileSize startPos, - /* - #else - const Byte *inBuffer, - #endif - */ - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain, +SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *tempBuf[]) { UInt32 ci; - size_t tempSizes[3] = { 0, 0, 0}; - size_t tempSize3 = 0; + SizeT tempSizes[3] = { 0, 0, 0}; + SizeT tempSize3 = 0; Byte *tempBuf3 = 0; RINOK(CheckSupportedFolder(folder)); @@ -177,19 +155,19 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) { UInt32 si = 0; - CFileSize offset; - CFileSize inSize; + UInt64 offset; + UInt64 inSize; Byte *outBufCur = outBuffer; - size_t outSizeCur = outSize; + SizeT outSizeCur = outSize; if (folder->NumCoders == 4) { UInt32 indices[] = { 3, 2, 0 }; - CFileSize unpackSize = folder->UnpackSizes[ci]; + UInt64 unpackSize = folder->UnpackSizes[ci]; si = indices[ci]; if (ci < 2) { Byte *temp; - outSizeCur = (size_t)unpackSize; + outSizeCur = (SizeT)unpackSize; if (outSizeCur != unpackSize) return SZ_ERROR_MEM; temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); @@ -200,58 +178,27 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, } else if (ci == 2) { - if (unpackSize > outSize) // check it - return SZ_ERROR_PARAM; // check it + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (size_t)unpackSize; + tempSize3 = outSizeCur = (SizeT)unpackSize; } else return SZ_ERROR_UNSUPPORTED; } offset = GetSum(packSizes, si); inSize = packSizes[si]; - /* - #ifdef _LZMA_IN_CB - */ - RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET)); - /* - #endif - */ + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); if (coder->MethodID == k_Copy) { - if (inSize != outSizeCur) // check it + if (inSize != outSizeCur) /* check it */ return SZ_ERROR_DATA; - - /* - #ifdef _LZMA_IN_CB - */ RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - /* - #else - memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize); - #endif - */ } else { - /* - #ifdef _LZMA_IN_CB - */ - SRes res = SzDecodeLzma(coder, inSize, - inStream, - outBufCur, outSizeCur, allocMain); - /* - #else - SizeT lzmaOutSizeT = outSizeCur; - SizeT lzmaInSizeT = (SizeT)inSize; - SRes res = LzmaDecode(outBufCur, &lzmaOutSizeT, - inBuffer + (size_t)offset, &lzmaInSizeT, - coder->Props.Items, (unsigned)coder->Props.size, LZMA_FINISH_BYTE, allocMain); - #endif - */ - - RINOK(res); + RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); } } else if (coder->MethodID == k_BCJ) @@ -264,17 +211,13 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, } else if (coder->MethodID == k_BCJ2) { - CFileSize offset = GetSum(packSizes, 1); - CFileSize s3Size = packSizes[1]; + UInt64 offset = GetSum(packSizes, 1); + UInt64 s3Size = packSizes[1]; SRes res; if (ci != 3) return SZ_ERROR_UNSUPPORTED; - - /* - #ifdef _LZMA_IN_CB - */ - RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET)); - tempSizes[2] = (size_t)s3Size; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + tempSizes[2] = (SizeT)s3Size; if (tempSizes[2] != s3Size) return SZ_ERROR_MEM; tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); @@ -282,23 +225,12 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, return SZ_ERROR_MEM; res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); RINOK(res) - /* - #endif - */ res = Bcj2_Decode( tempBuf3, tempSize3, tempBuf[0], tempSizes[0], tempBuf[1], tempSizes[1], - /* - #ifdef _LZMA_IN_CB - */ tempBuf[2], tempSizes[2], - /* - #else - inBuffer + (size_t)offset, (size_t)s3Size, - #endif - */ outBuffer, outSize); RINOK(res) } @@ -308,31 +240,14 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, return SZ_OK; } -SRes SzDecode(const CFileSize *packSizes, const CSzFolder *folder, - /* - #ifdef _LZMA_IN_CB - */ - ISzInStream *inStream, CFileSize startPos, - /* - #else - const Byte *inBuffer, - #endif - */ +SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, + ILookInStream *inStream, UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) { Byte *tempBuf[3] = { 0, 0, 0}; int i; - SRes res = SzDecode2(packSizes, folder, - /* - #ifdef _LZMA_IN_CB - */ - inStream, startPos, - /* - #else - inBuffer, - #endif - */ - outBuffer, outSize, allocMain, tempBuf); + SRes res = SzDecode2(packSizes, folder, inStream, startPos, + outBuffer, (SizeT)outSize, allocMain, tempBuf); for (i = 0; i < 3; i++) IAlloc_Free(allocMain, tempBuf[i]); return res; diff --git a/C/Archive/7z/7zDecode.h b/C/Archive/7z/7zDecode.h index 5b0996d7..e19fe387 100755 --- a/C/Archive/7z/7zDecode.h +++ b/C/Archive/7z/7zDecode.h @@ -1,26 +1,13 @@ /* 7zDecode.h -- Decoding from 7z folder -2008-04-09 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zItem.h for license options */ +2008-11-23 : Igor Pavlov : Public domain */ #ifndef __7Z_DECODE_H #define __7Z_DECODE_H #include "7zItem.h" -#include "7zIn.h" - -SRes SzDecode(const CFileSize *packSizes, const CSzFolder *folder, - /* - #ifdef _LZMA_IN_CB - */ - ISzInStream *stream, CFileSize startPos, - /* - #else - const Byte *inBuffer, - #endif - */ +SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, + ILookInStream *stream, UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); #endif diff --git a/C/Archive/7z/7zExtract.c b/C/Archive/7z/7zExtract.c index cc727467..ff79802b 100755 --- a/C/Archive/7z/7zExtract.c +++ b/C/Archive/7z/7zExtract.c @@ -1,16 +1,13 @@ /* 7zExtract.c -- Extracting from 7z archive -2008-08-17 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zExtract.h for license options */ +2008-11-23 : Igor Pavlov : Public domain */ -#include "7zExtract.h" -#include "7zDecode.h" #include "../../7zCrc.h" +#include "7zDecode.h" +#include "7zExtract.h" SRes SzAr_Extract( const CSzArEx *p, - ISzInStream *inStream, + ILookInStream *inStream, UInt32 fileIndex, UInt32 *blockIndex, Byte **outBuffer, @@ -36,9 +33,9 @@ SRes SzAr_Extract( if (*outBuffer == 0 || *blockIndex != folderIndex) { CSzFolder *folder = p->db.Folders + folderIndex; - CFileSize unpackSizeSpec = SzFolder_GetUnpackSize(folder); + UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); size_t unpackSize = (size_t)unpackSizeSpec; - CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); + UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); if (unpackSize != unpackSizeSpec) return SZ_ERROR_MEM; @@ -46,7 +43,7 @@ SRes SzAr_Extract( IAlloc_Free(allocMain, *outBuffer); *outBuffer = 0; - RINOK(inStream->Seek(inStream, startOffset, SZ_SEEK_SET)); + RINOK(LookInStream_SeekTo(inStream, startOffset)); if (res == SZ_OK) { diff --git a/C/Archive/7z/7zExtract.h b/C/Archive/7z/7zExtract.h index 4aa197a6..5f78415f 100755 --- a/C/Archive/7z/7zExtract.h +++ b/C/Archive/7z/7zExtract.h @@ -1,8 +1,5 @@ /* 7zExtract.h -- Extracting from 7z archive -2008-08-05 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zItem.h for license options */ +2008-11-23 : Igor Pavlov : Public domain */ #ifndef __7Z_EXTRACT_H #define __7Z_EXTRACT_H @@ -31,7 +28,7 @@ Read 7zItem.h for license options */ SRes SzAr_Extract( const CSzArEx *db, - ISzInStream *inStream, + ILookInStream *inStream, UInt32 fileIndex, /* index of file */ UInt32 *blockIndex, /* index of solid block */ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ diff --git a/C/Archive/7z/7zHeader.c b/C/Archive/7z/7zHeader.c index 3edb8d00..e48faa48 100755 --- a/C/Archive/7z/7zHeader.c +++ b/C/Archive/7z/7zHeader.c @@ -1,8 +1,5 @@ /* 7zHeader.c -- 7z Headers -2008-04-09 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zHeader.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #include "7zHeader.h" diff --git a/C/Archive/7z/7zHeader.h b/C/Archive/7z/7zHeader.h index 325fe4c6..9941b6f7 100755 --- a/C/Archive/7z/7zHeader.h +++ b/C/Archive/7z/7zHeader.h @@ -1,7 +1,5 @@ /* 7zHeader.h -- 7z Headers -2008-07-14 -Copyright (c) 1999-2008 Igor Pavlov -Read LzmaDec.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __7Z_HEADER_H #define __7Z_HEADER_H diff --git a/C/Archive/7z/7zIn.c b/C/Archive/7z/7zIn.c index 6592e7f4..fa10ecff 100755 --- a/C/Archive/7z/7zIn.c +++ b/C/Archive/7z/7zIn.c @@ -1,12 +1,11 @@ /* 7zIn.c -- 7z Input functions -2008-08-17 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zIn.h for license options */ +2008-11-23 : Igor Pavlov : Public domain */ -#include "7zIn.h" -#include "7zDecode.h" #include "../../7zCrc.h" +#include "../../CpuArch.h" + +#include "7zDecode.h" +#include "7zIn.h" #define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } @@ -30,12 +29,12 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) } /* -CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const +UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const { return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; } -CFileSize GetFilePackSize(int fileIndex) const +UInt64 GetFilePackSize(int fileIndex) const { int folderIndex = FileIndexToFolderIndexMap[fileIndex]; if (folderIndex >= 0) @@ -54,7 +53,7 @@ CFileSize GetFilePackSize(int fileIndex) const static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) { UInt32 startPos = 0; - CFileSize startPosSize = 0; + UInt64 startPosSize = 0; UInt32 i; UInt32 folderIndex = 0; UInt32 indexInFolder = 0; @@ -65,7 +64,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) startPos += p->db.Folders[i].NumPackStreams; } - MY_ALLOC(CFileSize, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); + MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); for (i = 0; i < p->db.NumPackStreams; i++) { @@ -115,22 +114,22 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) } -CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) { - return p->ArchiveInfo.DataStartPosition + + return p->dataPos + p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; } -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize) +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) { UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; CSzFolder *folder = p->db.Folders + folderIndex; - CFileSize size = 0; + UInt64 size = 0; UInt32 i; for (i = 0; i < folder->NumPackStreams; i++) { - CFileSize t = size + p->db.PackSizes[packStreamIndex + i]; - if (t < size) // check it + UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; + if (t < size) /* check it */ return SZ_ERROR_FAIL; size = t; } @@ -173,58 +172,6 @@ SRes SzReadTime(const CObjectVector<CBuf> &dataVector, } */ -static SRes SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size) -{ - while (size > 0) - { - void *inBufferSpec; - size_t processedSize = size; - const Byte *inBuffer; - RINOK(inStream->Read(inStream, (void **)&inBufferSpec, &processedSize)); - inBuffer = (const Byte *)inBufferSpec; - if (processedSize == 0) - return SZ_ERROR_INPUT_EOF; - size -= processedSize; - do - *data++ = *inBuffer++; - while (--processedSize != 0); - } - return SZ_OK; -} - -static SRes SafeReadDirectByte(ISzInStream *inStream, Byte *data) -{ - return SafeReadDirect(inStream, data, 1); -} - -static SRes SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc) -{ - int i; - *value = 0; - for (i = 0; i < 4; i++) - { - Byte b; - RINOK(SafeReadDirectByte(inStream, &b)); - *value |= ((UInt32)b << (8 * i)); - *crc = CRC_UPDATE_BYTE(*crc, b); - } - return SZ_OK; -} - -static SRes SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc) -{ - int i; - *value = 0; - for (i = 0; i < 8; i++) - { - Byte b; - RINOK(SafeReadDirectByte(inStream, &b)); - *value |= ((UInt64)b << (8 * i)); - *crc = CRC_UPDATE_BYTE(*crc, b); - } - return SZ_OK; -} - static int TestSignatureCandidate(Byte *testBytes) { size_t i; @@ -295,14 +242,6 @@ static SRes SzReadNumber(CSzData *sd, UInt64 *value) return SZ_OK; } -static SRes SzReadSize(CSzData *sd, CFileSize *value) -{ - UInt64 value64; - RINOK(SzReadNumber(sd, &value64)); - *value = (CFileSize)value64; - return SZ_OK; -} - static SRes SzReadNumber32(CSzData *sd, UInt32 *value) { UInt64 value64; @@ -415,24 +354,24 @@ static SRes SzReadHashDigests( static SRes SzReadPackInfo( CSzData *sd, - CFileSize *dataOffset, + UInt64 *dataOffset, UInt32 *numPackStreams, - CFileSize **packSizes, + UInt64 **packSizes, Byte **packCRCsDefined, UInt32 **packCRCs, ISzAlloc *alloc) { UInt32 i; - RINOK(SzReadSize(sd, dataOffset)); + RINOK(SzReadNumber(sd, dataOffset)); RINOK(SzReadNumber32(sd, numPackStreams)); RINOK(SzWaitAttribute(sd, k7zIdSize)); - MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, alloc); + MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); for (i = 0; i < *numPackStreams; i++) { - RINOK(SzReadSize(sd, (*packSizes) + i)); + RINOK(SzReadNumber(sd, (*packSizes) + i)); } for (;;) @@ -498,7 +437,7 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) return SZ_ERROR_UNSUPPORTED; coder->MethodID = 0; for (j = 0; j < idSize; j++) - coder->MethodID |= (CMethodID)longID[idSize - 1 - j] << (8 * j); + coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); if ((mainByte & 0x10) != 0) { @@ -548,7 +487,7 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) for (i = 0; i < numBindPairs; i++) { - CBindPair *bindPair = folder->BindPairs + i;; + CBindPair *bindPair = folder->BindPairs + i; RINOK(SzReadNumber32(sd, &bindPair->InIndex)); RINOK(SzReadNumber32(sd, &bindPair->OutIndex)); } @@ -609,11 +548,11 @@ static SRes SzReadUnpackInfo( CSzFolder *folder = (*folders) + i; UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); - MY_ALLOC(CFileSize, folder->UnpackSizes, (size_t)numOutStreams, alloc); + MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); for (j = 0; j < numOutStreams; j++) { - RINOK(SzReadSize(sd, folder->UnpackSizes + j)); + RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); } } @@ -652,7 +591,7 @@ static SRes SzReadSubStreamsInfo( UInt32 numFolders, CSzFolder *folders, UInt32 *numUnpackStreams, - CFileSize **unpackSizes, + UInt64 **unpackSizes, Byte **digestsDefined, UInt32 **digests, ISzAlloc *allocTemp) @@ -696,7 +635,7 @@ static SRes SzReadSubStreamsInfo( } else { - *unpackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(CFileSize)); + *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); RINOM(*unpackSizes); *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); RINOM(*digestsDefined); @@ -710,7 +649,7 @@ static SRes SzReadSubStreamsInfo( v3.13 incorrectly worked with empty folders v4.07: we check that folder is empty */ - CFileSize sum = 0; + UInt64 sum = 0; UInt32 j; UInt32 numSubstreams = folders[i].NumUnpackStreams; if (numSubstreams == 0) @@ -718,8 +657,8 @@ static SRes SzReadSubStreamsInfo( if (type == k7zIdSize) for (j = 1; j < numSubstreams; j++) { - CFileSize size; - RINOK(SzReadSize(sd, &size)); + UInt64 size; + RINOK(SzReadNumber(sd, &size)); (*unpackSizes)[si++] = size; sum += size; } @@ -795,10 +734,10 @@ static SRes SzReadSubStreamsInfo( static SRes SzReadStreamsInfo( CSzData *sd, - CFileSize *dataOffset, + UInt64 *dataOffset, CSzAr *p, UInt32 *numUnpackStreams, - CFileSize **unpackSizes, /* allocTemp */ + UInt64 **unpackSizes, /* allocTemp */ Byte **digestsDefined, /* allocTemp */ UInt32 **digests, /* allocTemp */ ISzAlloc *alloc, @@ -917,7 +856,7 @@ static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, IS static SRes SzReadHeader2( CSzArEx *p, /* allocMain */ CSzData *sd, - CFileSize **unpackSizes, /* allocTemp */ + UInt64 **unpackSizes, /* allocTemp */ Byte **digestsDefined, /* allocTemp */ UInt32 **digests, /* allocTemp */ Byte **emptyStreamVector, /* allocTemp */ @@ -945,13 +884,13 @@ static SRes SzReadHeader2( if (type == k7zIdMainStreamsInfo) { RINOK(SzReadStreamsInfo(sd, - &p->ArchiveInfo.DataStartPosition, + &p->dataPos, &p->db, &numUnpackStreams, unpackSizes, digestsDefined, digests, allocMain, allocTemp)); - p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader; + p->dataPos += p->startPosAfterHeader; RINOK(SzReadID(sd, &type)); } @@ -1070,7 +1009,7 @@ static SRes SzReadHeader( ISzAlloc *allocMain, ISzAlloc *allocTemp) { - CFileSize *unpackSizes = 0; + UInt64 *unpackSizes = 0; Byte *digestsDefined = 0; UInt32 *digests = 0; Byte *emptyStreamVector = 0; @@ -1090,21 +1029,21 @@ static SRes SzReadHeader( } static SRes SzReadAndDecodePackedStreams2( - ISzInStream *inStream, + ILookInStream *inStream, CSzData *sd, CBuf *outBuffer, - CFileSize baseOffset, + UInt64 baseOffset, CSzAr *p, - CFileSize **unpackSizes, + UInt64 **unpackSizes, Byte **digestsDefined, UInt32 **digests, ISzAlloc *allocTemp) { UInt32 numUnpackStreams = 0; - CFileSize dataStartPos; + UInt64 dataStartPos; CSzFolder *folder; - CFileSize unpackSize; + UInt64 unpackSize; SRes res; RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, @@ -1118,7 +1057,7 @@ static SRes SzReadAndDecodePackedStreams2( folder = p->Folders; unpackSize = SzFolder_GetUnpackSize(folder); - RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET)); + RINOK(LookInStream_SeekTo(inStream, dataStartPos)); if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) return SZ_ERROR_MEM; @@ -1134,14 +1073,14 @@ static SRes SzReadAndDecodePackedStreams2( } static SRes SzReadAndDecodePackedStreams( - ISzInStream *inStream, + ILookInStream *inStream, CSzData *sd, CBuf *outBuffer, - CFileSize baseOffset, + UInt64 baseOffset, ISzAlloc *allocTemp) { CSzAr p; - CFileSize *unpackSizes = 0; + UInt64 *unpackSizes = 0; Byte *digestsDefined = 0; UInt32 *digests = 0; SRes res; @@ -1158,105 +1097,101 @@ static SRes SzReadAndDecodePackedStreams( static SRes SzArEx_Open2( CSzArEx *p, - ISzInStream *inStream, + ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) { - Byte signature[k7zSignatureSize]; - Byte version; - UInt32 crcFromArchive; - UInt64 nextHeaderOffset; - UInt64 nextHeaderSize; + Byte header[k7zStartHeaderSize]; + UInt64 nextHeaderOffset, nextHeaderSize; + size_t nextHeaderSizeT; UInt32 nextHeaderCRC; - UInt32 crc = 0; - CFileSize pos = 0; CBuf buffer; - CSzData sd; SRes res; - if (SafeReadDirect(inStream, signature, k7zSignatureSize) != SZ_OK) - return SZ_ERROR_NO_ARCHIVE; + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); - if (!TestSignatureCandidate(signature)) + if (!TestSignatureCandidate(header)) return SZ_ERROR_NO_ARCHIVE; - - /* - p.Clear(); - p.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; - */ - RINOK(SafeReadDirectByte(inStream, &version)); - if (version != k7zMajorVersion) + if (header[6] != k7zMajorVersion) return SZ_ERROR_UNSUPPORTED; - RINOK(SafeReadDirectByte(inStream, &version)); - RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive, &crc)); + nextHeaderOffset = GetUi64(header + 12); + nextHeaderSize = GetUi64(header + 20); + nextHeaderCRC = GetUi32(header + 28); - crc = CRC_INIT_VAL; - RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset, &crc)); - RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize, &crc)); - RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC, &crc)); - - pos = k7zStartHeaderSize; - p->ArchiveInfo.StartPositionAfterHeader = pos; + p->startPosAfterHeader = k7zStartHeaderSize; - if (CRC_GET_DIGEST(crc) != crcFromArchive) + if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) return SZ_ERROR_CRC; - if (nextHeaderSize == 0) + nextHeaderSizeT = (size_t)nextHeaderSize; + if (nextHeaderSizeT != nextHeaderSize) + return SZ_ERROR_MEM; + if (nextHeaderSizeT == 0) return SZ_OK; + if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || + nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) + return SZ_ERROR_NO_ARCHIVE; + + { + Int64 pos = 0; + RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); + if ((UInt64)pos < nextHeaderOffset || + (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || + (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + return SZ_ERROR_INPUT_EOF; + } - RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset), SZ_SEEK_SET)); + RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); - if (!Buf_Create(&buffer, (size_t)nextHeaderSize, allocTemp)) + if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) return SZ_ERROR_MEM; - res = SafeReadDirect(inStream, buffer.data, (size_t)nextHeaderSize); + res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); if (res == SZ_OK) { res = SZ_ERROR_ARCHIVE; - if (CrcCalc(buffer.data, (size_t)nextHeaderSize) == nextHeaderCRC) + if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) { - for (;;) + CSzData sd; + UInt64 type; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + if (res == SZ_OK) { - UInt64 type; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - if (res != SZ_OK) - break; - if (type == k7zIdHeader) - { - res = SzReadHeader(p, &sd, allocMain, allocTemp); - break; - } - if (type != k7zIdEncodedHeader) - { - res = SZ_ERROR_UNSUPPORTED; - break; - } + if (type == k7zIdEncodedHeader) { CBuf outBuffer; Buf_Init(&outBuffer); - res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, - p->ArchiveInfo.StartPositionAfterHeader, - allocTemp); + res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); if (res != SZ_OK) - { Buf_Free(&outBuffer, allocTemp); - break; + else + { + Buf_Free(&buffer, allocTemp); + buffer.data = outBuffer.data; + buffer.size = outBuffer.size; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); } - Buf_Free(&buffer, allocTemp); - buffer.data = outBuffer.data; - buffer.size = outBuffer.size; } } + if (res == SZ_OK) + { + if (type == k7zIdHeader) + res = SzReadHeader(p, &sd, allocMain, allocTemp); + else + res = SZ_ERROR_UNSUPPORTED; + } } } Buf_Free(&buffer, allocTemp); return res; } -SRes SzArEx_Open(CSzArEx *p, ISzInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) { SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); if (res != SZ_OK) diff --git a/C/Archive/7z/7zIn.h b/C/Archive/7z/7zIn.h index ba8a84f9..c8430a7b 100755 --- a/C/Archive/7z/7zIn.h +++ b/C/Archive/7z/7zIn.h @@ -1,8 +1,5 @@ /* 7zIn.h -- 7z Input functions -2008-08-05 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zItem.h for license options */ +2008-11-23 : Igor Pavlov : Public domain */ #ifndef __7Z_IN_H #define __7Z_IN_H @@ -12,41 +9,22 @@ Read 7zItem.h for license options */ typedef struct { - CFileSize StartPositionAfterHeader; - CFileSize DataStartPosition; -} CInArchiveInfo; - -typedef struct -{ CSzAr db; - CInArchiveInfo ArchiveInfo; + + UInt64 startPosAfterHeader; + UInt64 dataPos; + UInt32 *FolderStartPackStreamIndex; - CFileSize *PackStreamStartPositions; + UInt64 *PackStreamStartPositions; UInt32 *FolderStartFileIndex; UInt32 *FileIndexToFolderIndexMap; } CSzArEx; void SzArEx_Init(CSzArEx *p); void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); -CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize); - -typedef enum -{ - SZ_SEEK_SET = 0, - SZ_SEEK_CUR = 1, - SZ_SEEK_END = 2 -} ESzSeek; +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); -typedef struct -{ - SRes (*Read)(void *object, void **buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) < input(*size)) is allowed */ - SRes (*Seek)(void *object, CFileSize pos, ESzSeek origin); -} ISzInStream; - - /* Errors: SZ_ERROR_NO_ARCHIVE @@ -58,6 +36,6 @@ SZ_ERROR_INPUT_EOF SZ_ERROR_FAIL */ -SRes SzArEx_Open(CSzArEx *p, ISzInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); #endif diff --git a/C/Archive/7z/7zItem.c b/C/Archive/7z/7zItem.c index 2ebcf64c..db44571e 100755 --- a/C/Archive/7z/7zItem.c +++ b/C/Archive/7z/7zItem.c @@ -1,8 +1,5 @@ /* 7zItem.c -- 7z Items -2008-08-05 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read 7zItem.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #include "7zItem.h" @@ -72,7 +69,7 @@ int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) return -1; } -CFileSize SzFolder_GetUnpackSize(CSzFolder *p) +UInt64 SzFolder_GetUnpackSize(CSzFolder *p) { int i = (int)SzFolder_GetNumOutStreams(p); if (i == 0) diff --git a/C/Archive/7z/7zItem.h b/C/Archive/7z/7zItem.h index ede1a8c3..9f1366cd 100755 --- a/C/Archive/7z/7zItem.h +++ b/C/Archive/7z/7zItem.h @@ -1,30 +1,16 @@ /* 7zItem.h -- 7z Items -2008-07-09 -Igor Pavlov -Copyright (c) 1999-2008 Igor Pavlov -Read LzmaDec.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __7Z_ITEM_H #define __7Z_ITEM_H #include "../../7zBuf.h" -/* #define _SZ_FILE_SIZE_32 */ -/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/ - -#ifdef _SZ_FILE_SIZE_32 -typedef UInt32 CFileSize; -#else -typedef UInt64 CFileSize; -#endif - -typedef UInt64 CMethodID; - typedef struct { UInt32 NumInStreams; UInt32 NumOutStreams; - CMethodID MethodID; + UInt64 MethodID; CBuf Props; } CSzCoderInfo; @@ -42,7 +28,7 @@ typedef struct CSzCoderInfo *Coders; CBindPair *BindPairs; UInt32 *PackStreams; - CFileSize *UnpackSizes; + UInt64 *UnpackSizes; UInt32 NumCoders; UInt32 NumBindPairs; UInt32 NumPackStreams; @@ -53,10 +39,10 @@ typedef struct } CSzFolder; void SzFolder_Init(CSzFolder *p); -CFileSize SzFolder_GetUnpackSize(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); -CFileSize SzFolder_GetUnpackSize(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); typedef struct { @@ -67,7 +53,7 @@ typedef struct typedef struct { CNtfsFileTime MTime; - CFileSize Size; + UInt64 Size; char *Name; UInt32 FileCRC; @@ -82,7 +68,7 @@ void SzFile_Init(CSzFileItem *p); typedef struct { - CFileSize *PackSizes; + UInt64 *PackSizes; Byte *PackCRCsDefined; UInt32 *PackCRCs; CSzFolder *Folders; diff --git a/C/Archive/7z/7zMain.c b/C/Archive/7z/7zMain.c index 5bcf0ec8..0c20e8c3 100755 --- a/C/Archive/7z/7zMain.c +++ b/C/Archive/7z/7zMain.c @@ -1,34 +1,19 @@ /* 7zMain.c - Test application for 7z Decoder -2008-08-17 -Igor Pavlov -Public domain */ +2008-11-23 : Igor Pavlov : Public domain */ -#include <stdio.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> -#ifdef _WIN32 -#define USE_WINDOWS_FUNCTIONS -#endif - -#ifdef USE_WINDOWS_FUNCTIONS -#include <windows.h> -#endif - -#include "7zIn.h" -#include "7zExtract.h" -#include "7zAlloc.h" - #include "../../7zCrc.h" +#include "../../7zFile.h" +#include "../../7zVersion.h" +#include "7zAlloc.h" +#include "7zExtract.h" +#include "7zIn.h" -#ifdef USE_WINDOWS_FUNCTIONS -typedef HANDLE MY_FILE_HANDLE; -#else -typedef FILE *MY_FILE_HANDLE; -#endif - -void ConvertNumberToString(CFileSize value, char *s) +static void ConvertNumberToString(UInt64 value, char *s) { char temp[32]; int pos = 0; @@ -48,7 +33,7 @@ void ConvertNumberToString(CFileSize value, char *s) #define PERIOD_100 (PERIOD_4 * 25 - 1) #define PERIOD_400 (PERIOD_100 * 4 + 1) -void ConvertFileTimeToString(CNtfsFileTime *ft, char *s) +static void ConvertFileTimeToString(CNtfsFileTime *ft, char *s) { unsigned year, mon, day, hour, min, sec; UInt64 v64 = ft->Low | ((UInt64)ft->High << 32); @@ -99,140 +84,6 @@ void ConvertFileTimeToString(CNtfsFileTime *ft, char *s) sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec); } - -#ifdef USE_WINDOWS_FUNCTIONS -/* - ReadFile and WriteFile functions in Windows have BUG: - If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) - from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES - (Insufficient system resources exist to complete the requested service). -*/ -#define kChunkSizeMax (1 << 24) -#endif - -size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size) -{ - if (size == 0) - return 0; - #ifdef USE_WINDOWS_FUNCTIONS - { - size_t processedSize = 0; - do - { - DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size; - DWORD processedLoc = 0; - BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL); - data = (void *)((unsigned char *)data + processedLoc); - size -= processedLoc; - processedSize += processedLoc; - if (!res || processedLoc == 0) - break; - } - while (size > 0); - return processedSize; - } - #else - return fread(data, 1, size, file); - #endif -} - -size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size) -{ - if (size == 0) - return 0; - #ifdef USE_WINDOWS_FUNCTIONS - { - size_t processedSize = 0; - do - { - DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size; - DWORD processedLoc = 0; - BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL); - data = (void *)((unsigned char *)data + processedLoc); - size -= processedLoc; - processedSize += processedLoc; - if (!res) - break; - } - while (size > 0); - return processedSize; - } - #else - return fwrite(data, 1, size, file); - #endif -} - -int MyCloseFile(MY_FILE_HANDLE file) -{ - #ifdef USE_WINDOWS_FUNCTIONS - return (CloseHandle(file) != FALSE) ? 0 : 1; - #else - return fclose(file); - #endif -} - -typedef struct _CFileInStream -{ - ISzInStream InStream; - MY_FILE_HANDLE File; -} CFileInStream; - - -#define kBufferSize (1 << 12) -Byte g_Buffer[kBufferSize]; - -SRes SzFileReadImp(void *object, void **buffer, size_t *size) -{ - CFileInStream *s = (CFileInStream *)object; - if (*size > kBufferSize) - *size = kBufferSize; - *size = MyReadFile(s->File, g_Buffer, *size); - *buffer = g_Buffer; - return SZ_OK; -} - -SRes SzFileSeekImp(void *object, CFileSize pos, ESzSeek origin) -{ - CFileInStream *s = (CFileInStream *)object; - - #ifdef USE_WINDOWS_FUNCTIONS - { - LARGE_INTEGER value; - DWORD moveMethod; - value.LowPart = (DWORD)pos; - value.HighPart = (LONG)((UInt64)pos >> 32); - #ifdef _SZ_FILE_SIZE_32 - /* VC 6.0 has bug with >> 32 shifts. */ - value.HighPart = 0; - #endif - switch (origin) - { - case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; - case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; - case SZ_SEEK_END: moveMethod = FILE_END; break; - default: return SZ_ERROR_PARAM; - } - value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, moveMethod); - if (value.LowPart == 0xFFFFFFFF) - if (GetLastError() != NO_ERROR) - return SZ_ERROR_FAIL; - return SZ_OK; - } - #else - int moveMethod; - int res; - switch (origin) - { - case SZ_SEEK_SET: moveMethod = SEEK_SET; break; - case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; - case SZ_SEEK_END: moveMethod = SEEK_END; break; - default: return SZ_ERROR_PARAM; - } - res = fseek(s->File, (long)pos, moveMethod ); - return (res == 0) ? SZ_OK : SZ_ERROR_FAIL; - #endif -} - void PrintError(char *sz) { printf("\nERROR: %s\n", sz); @@ -241,12 +92,13 @@ void PrintError(char *sz) int MY_CDECL main(int numargs, char *args[]) { CFileInStream archiveStream; + CLookToRead lookStream; CSzArEx db; SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; - printf("\n7z ANSI-C Decoder 4.59 Copyright (c) 1999-2008 Igor Pavlov 2008-07-09\n"); + printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n"); if (numargs == 1) { printf( @@ -263,22 +115,18 @@ int MY_CDECL main(int numargs, char *args[]) return 1; } - archiveStream.File = - #ifdef USE_WINDOWS_FUNCTIONS - CreateFileA(args[2], GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (archiveStream.File == INVALID_HANDLE_VALUE) - #else - archiveStream.File = fopen(args[2], "rb"); - if (archiveStream.File == 0) - #endif + if (InFile_Open(&archiveStream.file, args[2])) { PrintError("can not open input file"); return 1; } - archiveStream.InStream.Read = SzFileReadImp; - archiveStream.InStream.Seek = SzFileSeekImp; + + FileInStream_CreateVTable(&archiveStream); + LookToRead_CreateVTable(&lookStream, False); + + lookStream.realStream = &archiveStream.s; + LookToRead_Init(&lookStream); allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; @@ -289,19 +137,14 @@ int MY_CDECL main(int numargs, char *args[]) CrcGenerateTable(); SzArEx_Init(&db); - res = SzArEx_Open(&db, &archiveStream.InStream, &allocImp, &allocTempImp); + res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; - int listCommand = 0; - int testCommand = 0; - int extractCommand = 0; - if (strcmp(command, "l") == 0) - listCommand = 1; - if (strcmp(command, "t") == 0) - testCommand = 1; - else if (strcmp(command, "e") == 0) - extractCommand = 1; + int listCommand = 0, testCommand = 0, extractCommand = 0; + if (strcmp(command, "l") == 0) listCommand = 1; + else if (strcmp(command, "t") == 0) testCommand = 1; + else if (strcmp(command, "e") == 0) extractCommand = 1; if (listCommand) { @@ -316,7 +159,7 @@ int MY_CDECL main(int numargs, char *args[]) else strcpy(t, " "); - printf("%10s %s %s\n", s, t, f->Name); + printf("%s %10s %s\n", t, s, f->Name); } } else if (testCommand || extractCommand) @@ -349,7 +192,7 @@ int MY_CDECL main(int numargs, char *args[]) printf("\n"); continue; } - res = SzAr_Extract(&db, &archiveStream.InStream, i, + res = SzAr_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); @@ -357,7 +200,7 @@ int MY_CDECL main(int numargs, char *args[]) break; if (!testCommand) { - MY_FILE_HANDLE outputHandle; + CSzFile outFile; size_t processedSize; char *fileName = f->Name; size_t nameLen = strlen(f->Name); @@ -368,28 +211,21 @@ int MY_CDECL main(int numargs, char *args[]) break; } - outputHandle = - #ifdef USE_WINDOWS_FUNCTIONS - CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_READ, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (outputHandle == INVALID_HANDLE_VALUE) - #else - fopen(fileName, "wb+"); - if (outputHandle == 0) - #endif + if (OutFile_Open(&outFile, fileName)) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } - processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed); - if (processedSize != outSizeProcessed) + processedSize = outSizeProcessed; + if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || + processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZ_ERROR_FAIL; break; } - if (MyCloseFile(outputHandle)) + if (File_Close(&outFile)) { PrintError("can not close output file"); res = SZ_ERROR_FAIL; @@ -408,7 +244,7 @@ int MY_CDECL main(int numargs, char *args[]) } SzArEx_Free(&db, &allocImp); - MyCloseFile(archiveStream.File); + File_Close(&archiveStream.file); if (res == SZ_OK) { printf("\nEverything is Ok\n"); diff --git a/C/Archive/7z/makefile b/C/Archive/7z/makefile index 76fdec01..c7bb05bd 100755 --- a/C/Archive/7z/makefile +++ b/C/Archive/7z/makefile @@ -4,10 +4,13 @@ PROG = 7zDec.exe C_OBJS = \ $O\7zBuf.obj \ + $O\7zBuf2.obj \ $O\7zCrc.obj \ $O\LzmaDec.obj \ $O\Bra86.obj \ $O\Bcj2.obj \ + $O\7zFile.obj \ + $O\7zStream.obj \ 7Z_OBJS = \ $O\7zAlloc.obj \ diff --git a/C/Archive/7z/makefile.gcc b/C/Archive/7z/makefile.gcc index 6d3da99c..2203dfc1 100755 --- a/C/Archive/7z/makefile.gcc +++ b/C/Archive/7z/makefile.gcc @@ -4,7 +4,7 @@ LIB = RM = rm -f CFLAGS = -c -O2 -Wall -OBJS = 7zAlloc.o 7zBuf.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o LzmaDec.o Bra86.o Bcj2.o +OBJS = 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o LzmaDec.o Bra86.o Bcj2.o 7zFile.o 7zStream.o all: $(PROG) @@ -17,6 +17,9 @@ $(PROG): $(OBJS) 7zBuf.o: ../../7zBuf.c $(CXX) $(CFLAGS) ../../7zBuf.c +7zBuf2.o: ../../7zBuf2.c + $(CXX) $(CFLAGS) ../../7zBuf2.c + 7zCrc.o: ../../7zCrc.c $(CXX) $(CFLAGS) ../../7zCrc.c @@ -47,6 +50,12 @@ Bra86.o: ../../Bra86.c Bcj2.o: ../../Bcj2.c $(CXX) $(CFLAGS) ../../Bcj2.c +7zFile.o: ../../7zFile.c + $(CXX) $(CFLAGS) ../../7zFile.c + +7zStream.o: ../../7zStream.c + $(CXX) $(CFLAGS) ../../7zStream.c + clean: -$(RM) $(PROG) $(OBJS) @@ -1,7 +1,5 @@ /* Bcj2.c -- Converter for x86 code (BCJ2) -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read Bra.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #include "Bcj2.h" @@ -1,7 +1,5 @@ /* Bcj2.h -- Converter for x86 code (BCJ2) -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -Read Bra.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __BCJ2_H #define __BCJ2_H @@ -1,7 +1,5 @@ -/* Bra.c -- converters for RISC code -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -Read Bra.h for license options */ +/* Bra.c -- Converters for RISC code +2008-10-04 : Igor Pavlov : Public domain */ #include "Bra.h" @@ -1,7 +1,5 @@ /* Bra.h -- Branch converters for executables -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read LzmaDec.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __BRA_H #define __BRA_H @@ -43,7 +41,7 @@ in CALL instructions to increase the compression ratio. UInt32 ip = 0; for () { - // size must be >= Alignment + LookAhead, if it's not last block + ; size must be >= Alignment + LookAhead, if it's not last block SizeT processed = Convert(data, size, ip, 1); data += processed; size -= processed; @@ -1,7 +1,5 @@ -/* Bra86.c -- converter for x86 code (BCJ) -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read Bra.h for license options */ +/* Bra86.c -- Converter for x86 code (BCJ) +2008-10-04 : Igor Pavlov : Public domain */ #include "Bra.h" diff --git a/C/BraIA64.c b/C/BraIA64.c index d2570922..0b4ee85b 100755 --- a/C/BraIA64.c +++ b/C/BraIA64.c @@ -1,7 +1,5 @@ -/* BraIA64.c -- converter for IA-64 code -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -Read Bra.h for license options */ +/* BraIA64.c -- Converter for IA-64 code +2008-10-04 : Igor Pavlov : Public domain */ #include "Bra.h" @@ -1,7 +1,5 @@ -/* LzFind.c -- Match finder for LZ algorithms -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read LzFind.h for license options */ +/* LzFind.c -- Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ #include <string.h> @@ -1,14 +1,5 @@ -/* LzFind.h -- Match finder for LZ algorithms -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -You can use any of the following license options: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - 3) Common Development and Distribution License (CDDL) Version 1.0 - 4) Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to this file, - while you keep this file unmodified. -*/ +/* LzFind.h -- Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __LZFIND_H #define __LZFIND_H diff --git a/C/LzFindMt.c b/C/LzFindMt.c index 82caeb29..b49cd76b 100755 --- a/C/LzFindMt.c +++ b/C/LzFindMt.c @@ -1,7 +1,5 @@ /* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read LzFind.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #include "LzHash.h" diff --git a/C/LzFindMt.h b/C/LzFindMt.h index e24ed471..2c7e462d 100755 --- a/C/LzFindMt.h +++ b/C/LzFindMt.h @@ -1,7 +1,5 @@ -/* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -Read LzFind.h for license options */ +/* LzFindMt.h -- multithreaded Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __LZFINDMT_H #define __LZFINDMT_H @@ -1,7 +1,5 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2008-03-26 -Copyright (c) 1999-2008 Igor Pavlov -Read LzFind.h for license options */ +/* LzHash.h -- HASH functions for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __LZHASH_H #define __LZHASH_H diff --git a/C/LzmaDec.c b/C/LzmaDec.c index 724d1c9f..d87eb191 100755 --- a/C/LzmaDec.c +++ b/C/LzmaDec.c @@ -1,7 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read LzmaDec.h for license options */ +2008-11-06 : Igor Pavlov : Public domain */ #include "LzmaDec.h" @@ -115,12 +113,7 @@ Read LzmaDec.h for license options */ StopCompilingDueBUG #endif -/* -#define LZMA_STREAM_WAS_FINISHED_ID (-1) -#define LZMA_SPEC_LEN_OFFSET (-3) -*/ - -const Byte kLiteralNextStates[kNumStates * 2] = +static const Byte kLiteralNextStates[kNumStates * 2] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 @@ -132,8 +125,8 @@ const Byte kLiteralNextStates[kNumStates * 2] = And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization Out: Result: - 0 - OK - 1 - Error + SZ_OK - OK + SZ_ERROR_DATA - Error p->remainLen: < kMatchSpecLenStart : normal remain = kMatchSpecLenStart : finished @@ -390,6 +383,8 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte len += kMatchMinLen; + if (limit == dicPos) + return SZ_ERROR_DATA; { SizeT rem = limit - dicPos; unsigned curLen = ((rem < len) ? (unsigned)rem : len); @@ -464,8 +459,6 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) } } -/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */ - static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) { do @@ -811,7 +804,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr p->buf = src; if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) return SZ_ERROR_DATA; - processed = p->buf - src; + processed = (SizeT)(p->buf - src); (*srcLen) += processed; src += processed; inSize -= processed; diff --git a/C/LzmaDec.h b/C/LzmaDec.h index be594a1c..98cdbe94 100755 --- a/C/LzmaDec.h +++ b/C/LzmaDec.h @@ -1,14 +1,5 @@ /* LzmaDec.h -- LZMA Decoder -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -You can use any of the following license options: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - 3) Common Development and Distribution License (CDDL) Version 1.0 - 4) Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to this file, - while you keep this file unmodified. -*/ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __LZMADEC_H #define __LZMADEC_H diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c index ccbdac97..0c92c532 100755 --- a/C/LzmaEnc.c +++ b/C/LzmaEnc.c @@ -1,7 +1,5 @@ /* LzmaEnc.c -- LZMA Encoder -2008-08-17 -Copyright (c) 1999-2008 Igor Pavlov -Read LzmaEnc.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #include <string.h> @@ -2092,6 +2090,8 @@ void LzmaEnc_Finish(CLzmaEncHandle pp) CLzmaEnc *p = (CLzmaEnc *)pp; if (p->mtMode) MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + pp = pp; #endif } @@ -2154,7 +2154,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, RangeEnc_Init(&p->rc); p->rc.outStream = &outStream.funcTable; - res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize); + res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); *unpackSize = (UInt32)(p->nowPos64 - nowPos64); *destLen -= outStream.rem; @@ -2181,7 +2181,7 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i for (;;) { - res = LzmaEnc_CodeOneBlock(pp, False, 0, 0); + res = LzmaEnc_CodeOneBlock(p, False, 0, 0); if (res != SZ_OK || p->finished != 0) break; if (progress != 0) diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h index 54b140e0..bfbc7d2b 100755 --- a/C/LzmaEnc.h +++ b/C/LzmaEnc.h @@ -1,7 +1,5 @@ /* LzmaEnc.h -- LZMA Encoder -2008-08-05 -Copyright (c) 1999-2008 Igor Pavlov -Read LzFind.h for license options */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __LZMAENC_H #define __LZMAENC_H diff --git a/C/LzmaLib/LzmaLibExports.c b/C/LzmaLib/LzmaLibExports.c index cc90cc0b..845545db 100755 --- a/C/LzmaLib/LzmaLibExports.c +++ b/C/LzmaLib/LzmaLibExports.c @@ -1,7 +1,5 @@ -/* LzmaLibExports.c -- LZMA library DLL Entry point -2008-03-26 -Igor Pavlov -Public domain */ +/* LzmaLibExports.c -- LZMA library DLL Entry point +2008-10-04 : Igor Pavlov : Public domain */ #include <windows.h> 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; } diff --git a/C/LzmaUtil/LzmaUtil.dsp b/C/LzmaUtil/LzmaUtil.dsp index 77c03edd..faac2e6e 100755 --- a/C/LzmaUtil/LzmaUtil.dsp +++ b/C/LzmaUtil/LzmaUtil.dsp @@ -86,6 +86,22 @@ LINK32=link.exe # Name "LzmaUtil - Win32 Debug" # Begin Source File +SOURCE=..\7zFile.c +# End Source File +# Begin Source File + +SOURCE=..\7zFile.h +# End Source File +# Begin Source File + +SOURCE=..\7zStream.c +# End Source File +# Begin Source File + +SOURCE=..\7zVersion.h +# End Source File +# Begin Source File + SOURCE=..\Alloc.c # End Source File # Begin Source File diff --git a/C/LzmaUtil/makefile b/C/LzmaUtil/makefile index 11cada4e..fbb98b84 100755 --- a/C/LzmaUtil/makefile +++ b/C/LzmaUtil/makefile @@ -13,6 +13,8 @@ C_OBJS = \ $O\LzFindMt.obj \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ + $O\7zFile.obj \ + $O\7zStream.obj \ $O\Threads.obj \ OBJS = \ diff --git a/C/LzmaUtil/makefile.gcc b/C/LzmaUtil/makefile.gcc index 1d3442bc..9fcdeadb 100755 --- a/C/LzmaUtil/makefile.gcc +++ b/C/LzmaUtil/makefile.gcc @@ -10,6 +10,8 @@ OBJS = \ LzFind.o \ LzmaDec.o \ LzmaEnc.o \ + 7zFile.o \ + 7zStream.o \ all: $(PROG) @@ -32,5 +34,11 @@ LzmaDec.o: ../LzmaDec.c LzmaEnc.o: ../LzmaEnc.c $(CXX) $(CFLAGS) ../LzmaEnc.c +7zFile.o: ../7zFile.c + $(CXX) $(CFLAGS) ../7zFile.c + +7zStream.o: ../7zStream.c + $(CXX) $(CFLAGS) ../7zStream.c + clean: -$(RM) $(PROG) $(OBJS) @@ -1,8 +1,6 @@ /* Crypto/Sha256.c -- SHA-256 Hash function -2008-08-05 -This code is based on public domain code from Wei Dai's Crypto++ library. -Igor Pavlov -Public domain */ +2008-11-06 : Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ #include "Sha256.h" #include "RotateDefs.h" @@ -1,7 +1,5 @@ /* Crypto/Sha256.h -- SHA-256 Hash function -2008-08-05 -Igor Pavlov -Public domain */ +2008-10-04 : Igor Pavlov : Public domain */ #ifndef __CRYPTO_SHA256_H #define __CRYPTO_SHA256_H diff --git a/C/Threads.h b/C/Threads.h index 03bea106..a823e578 100755 --- a/C/Threads.h +++ b/C/Threads.h @@ -1,13 +1,9 @@ /* Threads.h -- multithreading library -2008-04-11 -Igor Pavlov -Public domain */ +2008-11-22 : Igor Pavlov : Public domain */ #ifndef __7Z_THRESDS_H #define __7Z_THRESDS_H -#include <windows.h> - #include "Types.h" typedef struct _CThread @@ -22,8 +18,6 @@ typedef unsigned THREAD_FUNC_RET_TYPE; #define THREAD_FUNC_CALL_TYPE MY_STD_CALL #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE -typedef DWORD WRes; - WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter); WRes Thread_Wait(CThread *thread); WRes Thread_Close(CThread *thread); @@ -1,11 +1,15 @@ /* Types.h -- Basic types -2008-08-05 -Igor Pavlov -Public domain */ +2008-11-23 : Igor Pavlov : Public domain */ #ifndef __7Z_TYPES_H #define __7Z_TYPES_H +#include <stddef.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + #define SZ_OK 0 #define SZ_ERROR_DATA 1 @@ -26,6 +30,12 @@ Public domain */ typedef int SRes; +#ifdef _WIN32 +typedef DWORD WRes; +#else +typedef int WRes; +#endif + #ifndef RINOK #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #endif @@ -42,11 +52,11 @@ typedef int Int32; typedef unsigned int UInt32; #endif -/* #define _SZ_NO_INT_64 */ -/* define it if your compiler doesn't support 64-bit integers */ - #ifdef _SZ_NO_INT_64 +/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. + NOTES: Some code will work incorrectly in that case! */ + typedef long Int64; typedef unsigned long UInt64; @@ -65,7 +75,6 @@ typedef unsigned long long int UInt64; #ifdef _LZMA_NO_SYSTEM_SIZE_T typedef UInt32 SizeT; #else -#include <stddef.h> typedef size_t SizeT; #endif @@ -104,13 +113,82 @@ typedef struct (output(*size) < input(*size)) is allowed */ } ISeqInStream; +/* it can return SZ_ERROR_INPUT_EOF */ +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); + typedef struct { size_t (*Write)(void *p, const void *buf, size_t size); /* Returns: result - the number of actually written bytes. - (result < size) means error */ + (result < size) means error */ } ISeqOutStream; +typedef enum +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ISeekInStream; + +typedef struct +{ + SRes (*Look)(void *p, void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(void *p, size_t offset); + /* offset must be <= output(*size) of Look */ + + SRes (*Read)(void *p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ILookInStream; + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); + +#define LookToRead_BUF_SIZE (1 << 14) + +typedef struct +{ + ILookInStream s; + ISeekInStream *realStream; + size_t pos; + size_t size; + Byte buf[LookToRead_BUF_SIZE]; +} CLookToRead; + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead); +void LookToRead_Init(CLookToRead *p); + +typedef struct +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + +typedef struct +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + typedef struct { SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); |