BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / linux / linux-2.6 / scripts / squashfs / lzma / C / 7zip / Archive / 7z_C / 7zExtract.c
blob21fb0131a0707a2abe463801b1d07498f674465a
1 /* 7zExtract.c */
3 #include "7zExtract.h"
4 #include "7zDecode.h"
5 #include "7zCrc.h"
7 SZ_RESULT SzExtract(
8 ISzInStream *inStream,
9 CArchiveDatabaseEx *db,
10 UInt32 fileIndex,
11 UInt32 *blockIndex,
12 Byte **outBuffer,
13 size_t *outBufferSize,
14 size_t *offset,
15 size_t *outSizeProcessed,
16 ISzAlloc *allocMain,
17 ISzAlloc *allocTemp)
19 UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
20 SZ_RESULT res = SZ_OK;
21 *offset = 0;
22 *outSizeProcessed = 0;
23 if (folderIndex == (UInt32)-1)
25 allocMain->Free(*outBuffer);
26 *blockIndex = folderIndex;
27 *outBuffer = 0;
28 *outBufferSize = 0;
29 return SZ_OK;
32 if (*outBuffer == 0 || *blockIndex != folderIndex)
34 CFolder *folder = db->Database.Folders + folderIndex;
35 CFileSize unPackSize = SzFolderGetUnPackSize(folder);
36 #ifndef _LZMA_IN_CB
37 CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
38 Byte *inBuffer = 0;
39 size_t processedSize;
40 #endif
41 *blockIndex = folderIndex;
42 allocMain->Free(*outBuffer);
43 *outBuffer = 0;
45 RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
47 #ifndef _LZMA_IN_CB
48 if (packSize != 0)
50 inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
51 if (inBuffer == 0)
52 return SZE_OUTOFMEMORY;
54 res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
55 if (res == SZ_OK && processedSize != (size_t)packSize)
56 res = SZE_FAIL;
57 #endif
58 if (res == SZ_OK)
60 *outBufferSize = (size_t)unPackSize;
61 if (unPackSize != 0)
63 *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
64 if (*outBuffer == 0)
65 res = SZE_OUTOFMEMORY;
67 if (res == SZ_OK)
69 size_t outRealSize;
70 res = SzDecode(db->Database.PackSizes +
71 db->FolderStartPackStreamIndex[folderIndex], folder,
72 #ifdef _LZMA_IN_CB
73 inStream,
74 #else
75 inBuffer,
76 #endif
77 *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
78 if (res == SZ_OK)
80 if (outRealSize == (size_t)unPackSize)
82 if (folder->UnPackCRCDefined)
84 if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
85 res = SZE_FAIL;
88 else
89 res = SZE_FAIL;
93 #ifndef _LZMA_IN_CB
94 allocTemp->Free(inBuffer);
95 #endif
97 if (res == SZ_OK)
99 UInt32 i;
100 CFileItem *fileItem = db->Database.Files + fileIndex;
101 *offset = 0;
102 for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
103 *offset += (UInt32)db->Database.Files[i].Size;
104 *outSizeProcessed = (size_t)fileItem->Size;
105 if (*offset + *outSizeProcessed > *outBufferSize)
106 return SZE_FAIL;
108 if (fileItem->IsFileCRCDefined)
110 if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
111 res = SZE_FAIL;
115 return res;