... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Mon Aug 17 13:54:09 CEST 2009 (acab) |
|
2 |
+------------------------------------ |
|
3 |
+ * libclamav/7z: convert EOL to unix for compat with suncc |
|
4 |
+ |
|
1 | 5 |
Fri Aug 14 14:37:21 CEST 2009 (tk) |
2 | 6 |
---------------------------------- |
3 | 7 |
* libclamav: improve handling of signature offsets |
... | ... |
@@ -1,36 +1,36 @@ |
1 |
-/* 7zBuf.c -- Byte Buffer |
|
2 |
-2008-03-28 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#include "7zBuf.h" |
|
7 |
- |
|
8 |
-void Buf_Init(CBuf *p) |
|
9 |
-{ |
|
10 |
- p->data = 0; |
|
11 |
- p->size = 0; |
|
12 |
-} |
|
13 |
- |
|
14 |
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) |
|
15 |
-{ |
|
16 |
- p->size = 0; |
|
17 |
- if (size == 0) |
|
18 |
- { |
|
19 |
- p->data = 0; |
|
20 |
- return 1; |
|
21 |
- } |
|
22 |
- p->data = (Byte *)alloc->Alloc(alloc, size); |
|
23 |
- if (p->data != 0) |
|
24 |
- { |
|
25 |
- p->size = size; |
|
26 |
- return 1; |
|
27 |
- } |
|
28 |
- return 0; |
|
29 |
-} |
|
30 |
- |
|
31 |
-void Buf_Free(CBuf *p, ISzAlloc *alloc) |
|
32 |
-{ |
|
33 |
- alloc->Free(alloc, p->data); |
|
34 |
- p->data = 0; |
|
35 |
- p->size = 0; |
|
36 |
-} |
|
1 |
+/* 7zBuf.c -- Byte Buffer |
|
2 |
+2008-03-28 |
|
3 |
+Igor Pavlov |
|
4 |
+Public domain */ |
|
5 |
+ |
|
6 |
+#include "7zBuf.h" |
|
7 |
+ |
|
8 |
+void Buf_Init(CBuf *p) |
|
9 |
+{ |
|
10 |
+ p->data = 0; |
|
11 |
+ p->size = 0; |
|
12 |
+} |
|
13 |
+ |
|
14 |
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) |
|
15 |
+{ |
|
16 |
+ p->size = 0; |
|
17 |
+ if (size == 0) |
|
18 |
+ { |
|
19 |
+ p->data = 0; |
|
20 |
+ return 1; |
|
21 |
+ } |
|
22 |
+ p->data = (Byte *)alloc->Alloc(alloc, size); |
|
23 |
+ if (p->data != 0) |
|
24 |
+ { |
|
25 |
+ p->size = size; |
|
26 |
+ return 1; |
|
27 |
+ } |
|
28 |
+ return 0; |
|
29 |
+} |
|
30 |
+ |
|
31 |
+void Buf_Free(CBuf *p, ISzAlloc *alloc) |
|
32 |
+{ |
|
33 |
+ alloc->Free(alloc, p->data); |
|
34 |
+ p->data = 0; |
|
35 |
+ p->size = 0; |
|
36 |
+} |
... | ... |
@@ -1,31 +1,31 @@ |
1 |
-/* 7zBuf.h -- Byte Buffer |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_BUF_H |
|
5 |
-#define __7Z_BUF_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-typedef struct |
|
10 |
-{ |
|
11 |
- Byte *data; |
|
12 |
- size_t size; |
|
13 |
-} CBuf; |
|
14 |
- |
|
15 |
-void Buf_Init(CBuf *p); |
|
16 |
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); |
|
17 |
-void Buf_Free(CBuf *p, ISzAlloc *alloc); |
|
18 |
- |
|
19 |
-typedef struct |
|
20 |
-{ |
|
21 |
- Byte *data; |
|
22 |
- size_t size; |
|
23 |
- size_t pos; |
|
24 |
-} CDynBuf; |
|
25 |
- |
|
26 |
-void DynBuf_Construct(CDynBuf *p); |
|
27 |
-void DynBuf_SeekToBeg(CDynBuf *p); |
|
28 |
-int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); |
|
29 |
-void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); |
|
30 |
- |
|
31 |
-#endif |
|
1 |
+/* 7zBuf.h -- Byte Buffer |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_BUF_H |
|
5 |
+#define __7Z_BUF_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+typedef struct |
|
10 |
+{ |
|
11 |
+ Byte *data; |
|
12 |
+ size_t size; |
|
13 |
+} CBuf; |
|
14 |
+ |
|
15 |
+void Buf_Init(CBuf *p); |
|
16 |
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); |
|
17 |
+void Buf_Free(CBuf *p, ISzAlloc *alloc); |
|
18 |
+ |
|
19 |
+typedef struct |
|
20 |
+{ |
|
21 |
+ Byte *data; |
|
22 |
+ size_t size; |
|
23 |
+ size_t pos; |
|
24 |
+} CDynBuf; |
|
25 |
+ |
|
26 |
+void DynBuf_Construct(CDynBuf *p); |
|
27 |
+void DynBuf_SeekToBeg(CDynBuf *p); |
|
28 |
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); |
|
29 |
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); |
|
30 |
+ |
|
31 |
+#endif |
... | ... |
@@ -1,24 +1,24 @@ |
1 |
-/* 7zCrc.c -- CRC32 calculation |
|
2 |
-2008-08-05 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#include "7zCrc.h" |
|
7 |
- |
|
8 |
-#define kCrcPoly 0xEDB88320 |
|
9 |
-/* aCaB - Make the table a global const */ |
|
10 |
-const UInt32 g_CrcTable[256] = { 0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; |
|
11 |
- |
|
12 |
- |
|
13 |
-UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) |
|
14 |
-{ |
|
15 |
- const Byte *p = (const Byte *)data; |
|
16 |
- for (; size > 0 ; size--, p++) |
|
17 |
- v = CRC_UPDATE_BYTE(v, *p); |
|
18 |
- return v; |
|
19 |
-} |
|
20 |
- |
|
21 |
-UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) |
|
22 |
-{ |
|
23 |
- return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; |
|
24 |
-} |
|
1 |
+/* 7zCrc.c -- CRC32 calculation |
|
2 |
+2008-08-05 |
|
3 |
+Igor Pavlov |
|
4 |
+Public domain */ |
|
5 |
+ |
|
6 |
+#include "7zCrc.h" |
|
7 |
+ |
|
8 |
+#define kCrcPoly 0xEDB88320 |
|
9 |
+/* aCaB - Make the table a global const */ |
|
10 |
+const UInt32 g_CrcTable[256] = { 0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; |
|
11 |
+ |
|
12 |
+ |
|
13 |
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) |
|
14 |
+{ |
|
15 |
+ const Byte *p = (const Byte *)data; |
|
16 |
+ for (; size > 0 ; size--, p++) |
|
17 |
+ v = CRC_UPDATE_BYTE(v, *p); |
|
18 |
+ return v; |
|
19 |
+} |
|
20 |
+ |
|
21 |
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) |
|
22 |
+{ |
|
23 |
+ return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; |
|
24 |
+} |
... | ... |
@@ -1,24 +1,24 @@ |
1 |
-/* 7zCrc.h -- CRC32 calculation |
|
2 |
-2008-03-13 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#ifndef __7Z_CRC_H |
|
7 |
-#define __7Z_CRC_H |
|
8 |
- |
|
9 |
-#include <stddef.h> |
|
10 |
- |
|
11 |
-#include "Types.h" |
|
12 |
- |
|
13 |
-extern const UInt32 g_CrcTable[]; |
|
14 |
- |
|
15 |
-void MY_FAST_CALL CrcGenerateTable(void); |
|
16 |
- |
|
17 |
-#define CRC_INIT_VAL 0xFFFFFFFF |
|
18 |
-#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) |
|
19 |
-#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
20 |
- |
|
21 |
-UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); |
|
22 |
-UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); |
|
23 |
- |
|
24 |
-#endif |
|
1 |
+/* 7zCrc.h -- CRC32 calculation |
|
2 |
+2008-03-13 |
|
3 |
+Igor Pavlov |
|
4 |
+Public domain */ |
|
5 |
+ |
|
6 |
+#ifndef __7Z_CRC_H |
|
7 |
+#define __7Z_CRC_H |
|
8 |
+ |
|
9 |
+#include <stddef.h> |
|
10 |
+ |
|
11 |
+#include "Types.h" |
|
12 |
+ |
|
13 |
+extern const UInt32 g_CrcTable[]; |
|
14 |
+ |
|
15 |
+void MY_FAST_CALL CrcGenerateTable(void); |
|
16 |
+ |
|
17 |
+#define CRC_INIT_VAL 0xFFFFFFFF |
|
18 |
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) |
|
19 |
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
20 |
+ |
|
21 |
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); |
|
22 |
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); |
|
23 |
+ |
|
24 |
+#endif |
... | ... |
@@ -1,263 +1,263 @@ |
1 |
-/* 7zFile.c -- File IO |
|
2 |
-2008-11-22 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "7zFile.h" |
|
5 |
- |
|
6 |
-#ifndef USE_WINDOWS_FILE |
|
7 |
- |
|
8 |
-#include <errno.h> |
|
9 |
- |
|
10 |
-#endif |
|
11 |
- |
|
12 |
-#ifdef USE_WINDOWS_FILE |
|
13 |
- |
|
14 |
-/* |
|
15 |
- ReadFile and WriteFile functions in Windows have BUG: |
|
16 |
- If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) |
|
17 |
- from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES |
|
18 |
- (Insufficient system resources exist to complete the requested service). |
|
19 |
- Probably in some version of Windows there are problems with other sizes: |
|
20 |
- for 32 MB (maybe also for 16 MB). |
|
21 |
- And message can be "Network connection was lost" |
|
22 |
-*/ |
|
23 |
- |
|
24 |
-#define kChunkSizeMax (1 << 22) |
|
25 |
- |
|
26 |
-#endif |
|
27 |
- |
|
28 |
-void File_Construct(CSzFile *p) |
|
29 |
-{ |
|
30 |
- #ifdef USE_WINDOWS_FILE |
|
31 |
- p->handle = INVALID_HANDLE_VALUE; |
|
32 |
- #else |
|
33 |
- p->file = NULL; |
|
34 |
- #endif |
|
35 |
-} |
|
36 |
- |
|
37 |
-static WRes File_Open(CSzFile *p, const char *name, int writeMode) |
|
38 |
-{ |
|
39 |
- #ifdef USE_WINDOWS_FILE |
|
40 |
- p->handle = CreateFileA(name, |
|
41 |
- writeMode ? GENERIC_WRITE : GENERIC_READ, |
|
42 |
- FILE_SHARE_READ, NULL, |
|
43 |
- writeMode ? CREATE_ALWAYS : OPEN_EXISTING, |
|
44 |
- FILE_ATTRIBUTE_NORMAL, NULL); |
|
45 |
- return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); |
|
46 |
- #else |
|
47 |
- p->file = fopen(name, writeMode ? "wb+" : "rb"); |
|
48 |
- return (p->file != 0) ? 0 : errno; |
|
49 |
- #endif |
|
50 |
-} |
|
51 |
- |
|
52 |
-WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } |
|
53 |
-WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } |
|
54 |
- |
|
55 |
-WRes File_Close(CSzFile *p) |
|
56 |
-{ |
|
57 |
- #ifdef USE_WINDOWS_FILE |
|
58 |
- if (p->handle != INVALID_HANDLE_VALUE) |
|
59 |
- { |
|
60 |
- if (!CloseHandle(p->handle)) |
|
61 |
- return GetLastError(); |
|
62 |
- p->handle = INVALID_HANDLE_VALUE; |
|
63 |
- } |
|
64 |
- #else |
|
65 |
- if (p->file != NULL) |
|
66 |
- { |
|
67 |
- int res = fclose(p->file); |
|
68 |
- if (res != 0) |
|
69 |
- return res; |
|
70 |
- p->file = NULL; |
|
71 |
- } |
|
72 |
- #endif |
|
73 |
- return 0; |
|
74 |
-} |
|
75 |
- |
|
76 |
-WRes File_Read(CSzFile *p, void *data, size_t *size) |
|
77 |
-{ |
|
78 |
- size_t originalSize = *size; |
|
79 |
- if (originalSize == 0) |
|
80 |
- return 0; |
|
81 |
- |
|
82 |
- #ifdef USE_WINDOWS_FILE |
|
83 |
- |
|
84 |
- *size = 0; |
|
85 |
- do |
|
86 |
- { |
|
87 |
- DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
88 |
- DWORD processed = 0; |
|
89 |
- BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); |
|
90 |
- data = (void *)((Byte *)data + processed); |
|
91 |
- originalSize -= processed; |
|
92 |
- *size += processed; |
|
93 |
- if (!res) |
|
94 |
- return GetLastError(); |
|
95 |
- if (processed == 0) |
|
96 |
- break; |
|
97 |
- } |
|
98 |
- while (originalSize > 0); |
|
99 |
- return 0; |
|
100 |
- |
|
101 |
- #else |
|
102 |
- |
|
103 |
- *size = fread(data, 1, originalSize, p->file); |
|
104 |
- if (*size == originalSize) |
|
105 |
- return 0; |
|
106 |
- return ferror(p->file); |
|
107 |
- |
|
108 |
- #endif |
|
109 |
-} |
|
110 |
- |
|
111 |
-WRes File_Write(CSzFile *p, const void *data, size_t *size) |
|
112 |
-{ |
|
113 |
- size_t originalSize = *size; |
|
114 |
- if (originalSize == 0) |
|
115 |
- return 0; |
|
116 |
- |
|
117 |
- #ifdef USE_WINDOWS_FILE |
|
118 |
- |
|
119 |
- *size = 0; |
|
120 |
- do |
|
121 |
- { |
|
122 |
- DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
123 |
- DWORD processed = 0; |
|
124 |
- BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); |
|
125 |
- data = (void *)((Byte *)data + processed); |
|
126 |
- originalSize -= processed; |
|
127 |
- *size += processed; |
|
128 |
- if (!res) |
|
129 |
- return GetLastError(); |
|
130 |
- if (processed == 0) |
|
131 |
- break; |
|
132 |
- } |
|
133 |
- while (originalSize > 0); |
|
134 |
- return 0; |
|
135 |
- |
|
136 |
- #else |
|
137 |
- |
|
138 |
- *size = fwrite(data, 1, originalSize, p->file); |
|
139 |
- if (*size == originalSize) |
|
140 |
- return 0; |
|
141 |
- return ferror(p->file); |
|
142 |
- |
|
143 |
- #endif |
|
144 |
-} |
|
145 |
- |
|
146 |
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) |
|
147 |
-{ |
|
148 |
- #ifdef USE_WINDOWS_FILE |
|
149 |
- |
|
150 |
- LARGE_INTEGER value; |
|
151 |
- DWORD moveMethod; |
|
152 |
- value.LowPart = (DWORD)*pos; |
|
153 |
- value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ |
|
154 |
- switch (origin) |
|
155 |
- { |
|
156 |
- case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; |
|
157 |
- case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; |
|
158 |
- case SZ_SEEK_END: moveMethod = FILE_END; break; |
|
159 |
- default: return ERROR_INVALID_PARAMETER; |
|
160 |
- } |
|
161 |
- value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); |
|
162 |
- if (value.LowPart == 0xFFFFFFFF) |
|
163 |
- { |
|
164 |
- WRes res = GetLastError(); |
|
165 |
- if (res != NO_ERROR) |
|
166 |
- return res; |
|
167 |
- } |
|
168 |
- *pos = ((Int64)value.HighPart << 32) | value.LowPart; |
|
169 |
- return 0; |
|
170 |
- |
|
171 |
- #else |
|
172 |
- |
|
173 |
- int moveMethod; |
|
174 |
- int res; |
|
175 |
- switch (origin) |
|
176 |
- { |
|
177 |
- case SZ_SEEK_SET: moveMethod = SEEK_SET; break; |
|
178 |
- case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; |
|
179 |
- case SZ_SEEK_END: moveMethod = SEEK_END; break; |
|
180 |
- default: return 1; |
|
181 |
- } |
|
182 |
- res = fseek(p->file, (long)*pos, moveMethod); |
|
183 |
- *pos = ftell(p->file); |
|
184 |
- return res; |
|
185 |
- |
|
186 |
- #endif |
|
187 |
-} |
|
188 |
- |
|
189 |
-WRes File_GetLength(CSzFile *p, UInt64 *length) |
|
190 |
-{ |
|
191 |
- #ifdef USE_WINDOWS_FILE |
|
192 |
- |
|
193 |
- DWORD sizeHigh; |
|
194 |
- DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); |
|
195 |
- if (sizeLow == 0xFFFFFFFF) |
|
196 |
- { |
|
197 |
- DWORD res = GetLastError(); |
|
198 |
- if (res != NO_ERROR) |
|
199 |
- return res; |
|
200 |
- } |
|
201 |
- *length = (((UInt64)sizeHigh) << 32) + sizeLow; |
|
202 |
- return 0; |
|
203 |
- |
|
204 |
- #else |
|
205 |
- |
|
206 |
- long pos = ftell(p->file); |
|
207 |
- int res = fseek(p->file, 0, SEEK_END); |
|
208 |
- *length = ftell(p->file); |
|
209 |
- fseek(p->file, pos, SEEK_SET); |
|
210 |
- return res; |
|
211 |
- |
|
212 |
- #endif |
|
213 |
-} |
|
214 |
- |
|
215 |
- |
|
216 |
-/* ---------- FileSeqInStream ---------- */ |
|
217 |
- |
|
218 |
-static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) |
|
219 |
-{ |
|
220 |
- CFileSeqInStream *p = (CFileSeqInStream *)pp; |
|
221 |
- return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; |
|
222 |
-} |
|
223 |
- |
|
224 |
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p) |
|
225 |
-{ |
|
226 |
- p->s.Read = FileSeqInStream_Read; |
|
227 |
-} |
|
228 |
- |
|
229 |
- |
|
230 |
-/* ---------- FileInStream ---------- */ |
|
231 |
- |
|
232 |
-static SRes FileInStream_Read(void *pp, void *buf, size_t *size) |
|
233 |
-{ |
|
234 |
- CFileInStream *p = (CFileInStream *)pp; |
|
235 |
- return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; |
|
236 |
-} |
|
237 |
- |
|
238 |
-static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
239 |
-{ |
|
240 |
- CFileInStream *p = (CFileInStream *)pp; |
|
241 |
- return File_Seek(&p->file, pos, origin); |
|
242 |
-} |
|
243 |
- |
|
244 |
-void FileInStream_CreateVTable(CFileInStream *p) |
|
245 |
-{ |
|
246 |
- p->s.Read = FileInStream_Read; |
|
247 |
- p->s.Seek = FileInStream_Seek; |
|
248 |
-} |
|
249 |
- |
|
250 |
- |
|
251 |
-/* ---------- FileOutStream ---------- */ |
|
252 |
- |
|
253 |
-static size_t FileOutStream_Write(void *pp, const void *data, size_t size) |
|
254 |
-{ |
|
255 |
- CFileOutStream *p = (CFileOutStream *)pp; |
|
256 |
- File_Write(&p->file, data, &size); |
|
257 |
- return size; |
|
258 |
-} |
|
259 |
- |
|
260 |
-void FileOutStream_CreateVTable(CFileOutStream *p) |
|
261 |
-{ |
|
262 |
- p->s.Write = FileOutStream_Write; |
|
263 |
-} |
|
1 |
+/* 7zFile.c -- File IO |
|
2 |
+2008-11-22 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "7zFile.h" |
|
5 |
+ |
|
6 |
+#ifndef USE_WINDOWS_FILE |
|
7 |
+ |
|
8 |
+#include <errno.h> |
|
9 |
+ |
|
10 |
+#endif |
|
11 |
+ |
|
12 |
+#ifdef USE_WINDOWS_FILE |
|
13 |
+ |
|
14 |
+/* |
|
15 |
+ ReadFile and WriteFile functions in Windows have BUG: |
|
16 |
+ If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) |
|
17 |
+ from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES |
|
18 |
+ (Insufficient system resources exist to complete the requested service). |
|
19 |
+ Probably in some version of Windows there are problems with other sizes: |
|
20 |
+ for 32 MB (maybe also for 16 MB). |
|
21 |
+ And message can be "Network connection was lost" |
|
22 |
+*/ |
|
23 |
+ |
|
24 |
+#define kChunkSizeMax (1 << 22) |
|
25 |
+ |
|
26 |
+#endif |
|
27 |
+ |
|
28 |
+void File_Construct(CSzFile *p) |
|
29 |
+{ |
|
30 |
+ #ifdef USE_WINDOWS_FILE |
|
31 |
+ p->handle = INVALID_HANDLE_VALUE; |
|
32 |
+ #else |
|
33 |
+ p->file = NULL; |
|
34 |
+ #endif |
|
35 |
+} |
|
36 |
+ |
|
37 |
+static WRes File_Open(CSzFile *p, const char *name, int writeMode) |
|
38 |
+{ |
|
39 |
+ #ifdef USE_WINDOWS_FILE |
|
40 |
+ p->handle = CreateFileA(name, |
|
41 |
+ writeMode ? GENERIC_WRITE : GENERIC_READ, |
|
42 |
+ FILE_SHARE_READ, NULL, |
|
43 |
+ writeMode ? CREATE_ALWAYS : OPEN_EXISTING, |
|
44 |
+ FILE_ATTRIBUTE_NORMAL, NULL); |
|
45 |
+ return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); |
|
46 |
+ #else |
|
47 |
+ p->file = fopen(name, writeMode ? "wb+" : "rb"); |
|
48 |
+ return (p->file != 0) ? 0 : errno; |
|
49 |
+ #endif |
|
50 |
+} |
|
51 |
+ |
|
52 |
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } |
|
53 |
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } |
|
54 |
+ |
|
55 |
+WRes File_Close(CSzFile *p) |
|
56 |
+{ |
|
57 |
+ #ifdef USE_WINDOWS_FILE |
|
58 |
+ if (p->handle != INVALID_HANDLE_VALUE) |
|
59 |
+ { |
|
60 |
+ if (!CloseHandle(p->handle)) |
|
61 |
+ return GetLastError(); |
|
62 |
+ p->handle = INVALID_HANDLE_VALUE; |
|
63 |
+ } |
|
64 |
+ #else |
|
65 |
+ if (p->file != NULL) |
|
66 |
+ { |
|
67 |
+ int res = fclose(p->file); |
|
68 |
+ if (res != 0) |
|
69 |
+ return res; |
|
70 |
+ p->file = NULL; |
|
71 |
+ } |
|
72 |
+ #endif |
|
73 |
+ return 0; |
|
74 |
+} |
|
75 |
+ |
|
76 |
+WRes File_Read(CSzFile *p, void *data, size_t *size) |
|
77 |
+{ |
|
78 |
+ size_t originalSize = *size; |
|
79 |
+ if (originalSize == 0) |
|
80 |
+ return 0; |
|
81 |
+ |
|
82 |
+ #ifdef USE_WINDOWS_FILE |
|
83 |
+ |
|
84 |
+ *size = 0; |
|
85 |
+ do |
|
86 |
+ { |
|
87 |
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
88 |
+ DWORD processed = 0; |
|
89 |
+ BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); |
|
90 |
+ data = (void *)((Byte *)data + processed); |
|
91 |
+ originalSize -= processed; |
|
92 |
+ *size += processed; |
|
93 |
+ if (!res) |
|
94 |
+ return GetLastError(); |
|
95 |
+ if (processed == 0) |
|
96 |
+ break; |
|
97 |
+ } |
|
98 |
+ while (originalSize > 0); |
|
99 |
+ return 0; |
|
100 |
+ |
|
101 |
+ #else |
|
102 |
+ |
|
103 |
+ *size = fread(data, 1, originalSize, p->file); |
|
104 |
+ if (*size == originalSize) |
|
105 |
+ return 0; |
|
106 |
+ return ferror(p->file); |
|
107 |
+ |
|
108 |
+ #endif |
|
109 |
+} |
|
110 |
+ |
|
111 |
+WRes File_Write(CSzFile *p, const void *data, size_t *size) |
|
112 |
+{ |
|
113 |
+ size_t originalSize = *size; |
|
114 |
+ if (originalSize == 0) |
|
115 |
+ return 0; |
|
116 |
+ |
|
117 |
+ #ifdef USE_WINDOWS_FILE |
|
118 |
+ |
|
119 |
+ *size = 0; |
|
120 |
+ do |
|
121 |
+ { |
|
122 |
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
123 |
+ DWORD processed = 0; |
|
124 |
+ BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); |
|
125 |
+ data = (void *)((Byte *)data + processed); |
|
126 |
+ originalSize -= processed; |
|
127 |
+ *size += processed; |
|
128 |
+ if (!res) |
|
129 |
+ return GetLastError(); |
|
130 |
+ if (processed == 0) |
|
131 |
+ break; |
|
132 |
+ } |
|
133 |
+ while (originalSize > 0); |
|
134 |
+ return 0; |
|
135 |
+ |
|
136 |
+ #else |
|
137 |
+ |
|
138 |
+ *size = fwrite(data, 1, originalSize, p->file); |
|
139 |
+ if (*size == originalSize) |
|
140 |
+ return 0; |
|
141 |
+ return ferror(p->file); |
|
142 |
+ |
|
143 |
+ #endif |
|
144 |
+} |
|
145 |
+ |
|
146 |
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) |
|
147 |
+{ |
|
148 |
+ #ifdef USE_WINDOWS_FILE |
|
149 |
+ |
|
150 |
+ LARGE_INTEGER value; |
|
151 |
+ DWORD moveMethod; |
|
152 |
+ value.LowPart = (DWORD)*pos; |
|
153 |
+ value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ |
|
154 |
+ switch (origin) |
|
155 |
+ { |
|
156 |
+ case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; |
|
157 |
+ case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; |
|
158 |
+ case SZ_SEEK_END: moveMethod = FILE_END; break; |
|
159 |
+ default: return ERROR_INVALID_PARAMETER; |
|
160 |
+ } |
|
161 |
+ value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); |
|
162 |
+ if (value.LowPart == 0xFFFFFFFF) |
|
163 |
+ { |
|
164 |
+ WRes res = GetLastError(); |
|
165 |
+ if (res != NO_ERROR) |
|
166 |
+ return res; |
|
167 |
+ } |
|
168 |
+ *pos = ((Int64)value.HighPart << 32) | value.LowPart; |
|
169 |
+ return 0; |
|
170 |
+ |
|
171 |
+ #else |
|
172 |
+ |
|
173 |
+ int moveMethod; |
|
174 |
+ int res; |
|
175 |
+ switch (origin) |
|
176 |
+ { |
|
177 |
+ case SZ_SEEK_SET: moveMethod = SEEK_SET; break; |
|
178 |
+ case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; |
|
179 |
+ case SZ_SEEK_END: moveMethod = SEEK_END; break; |
|
180 |
+ default: return 1; |
|
181 |
+ } |
|
182 |
+ res = fseek(p->file, (long)*pos, moveMethod); |
|
183 |
+ *pos = ftell(p->file); |
|
184 |
+ return res; |
|
185 |
+ |
|
186 |
+ #endif |
|
187 |
+} |
|
188 |
+ |
|
189 |
+WRes File_GetLength(CSzFile *p, UInt64 *length) |
|
190 |
+{ |
|
191 |
+ #ifdef USE_WINDOWS_FILE |
|
192 |
+ |
|
193 |
+ DWORD sizeHigh; |
|
194 |
+ DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); |
|
195 |
+ if (sizeLow == 0xFFFFFFFF) |
|
196 |
+ { |
|
197 |
+ DWORD res = GetLastError(); |
|
198 |
+ if (res != NO_ERROR) |
|
199 |
+ return res; |
|
200 |
+ } |
|
201 |
+ *length = (((UInt64)sizeHigh) << 32) + sizeLow; |
|
202 |
+ return 0; |
|
203 |
+ |
|
204 |
+ #else |
|
205 |
+ |
|
206 |
+ long pos = ftell(p->file); |
|
207 |
+ int res = fseek(p->file, 0, SEEK_END); |
|
208 |
+ *length = ftell(p->file); |
|
209 |
+ fseek(p->file, pos, SEEK_SET); |
|
210 |
+ return res; |
|
211 |
+ |
|
212 |
+ #endif |
|
213 |
+} |
|
214 |
+ |
|
215 |
+ |
|
216 |
+/* ---------- FileSeqInStream ---------- */ |
|
217 |
+ |
|
218 |
+static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) |
|
219 |
+{ |
|
220 |
+ CFileSeqInStream *p = (CFileSeqInStream *)pp; |
|
221 |
+ return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; |
|
222 |
+} |
|
223 |
+ |
|
224 |
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p) |
|
225 |
+{ |
|
226 |
+ p->s.Read = FileSeqInStream_Read; |
|
227 |
+} |
|
228 |
+ |
|
229 |
+ |
|
230 |
+/* ---------- FileInStream ---------- */ |
|
231 |
+ |
|
232 |
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size) |
|
233 |
+{ |
|
234 |
+ CFileInStream *p = (CFileInStream *)pp; |
|
235 |
+ return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; |
|
236 |
+} |
|
237 |
+ |
|
238 |
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
239 |
+{ |
|
240 |
+ CFileInStream *p = (CFileInStream *)pp; |
|
241 |
+ return File_Seek(&p->file, pos, origin); |
|
242 |
+} |
|
243 |
+ |
|
244 |
+void FileInStream_CreateVTable(CFileInStream *p) |
|
245 |
+{ |
|
246 |
+ p->s.Read = FileInStream_Read; |
|
247 |
+ p->s.Seek = FileInStream_Seek; |
|
248 |
+} |
|
249 |
+ |
|
250 |
+ |
|
251 |
+/* ---------- FileOutStream ---------- */ |
|
252 |
+ |
|
253 |
+static size_t FileOutStream_Write(void *pp, const void *data, size_t size) |
|
254 |
+{ |
|
255 |
+ CFileOutStream *p = (CFileOutStream *)pp; |
|
256 |
+ File_Write(&p->file, data, &size); |
|
257 |
+ return size; |
|
258 |
+} |
|
259 |
+ |
|
260 |
+void FileOutStream_CreateVTable(CFileOutStream *p) |
|
261 |
+{ |
|
262 |
+ p->s.Write = FileOutStream_Write; |
|
263 |
+} |
... | ... |
@@ -1,76 +1,76 @@ |
1 |
-/* 7zFile.h -- File IO |
|
2 |
-2008-11-22 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_FILE_H |
|
5 |
-#define __7Z_FILE_H |
|
6 |
- |
|
7 |
-/* aCaB -- do not use HANDLE on win32 |
|
8 |
-#ifdef _WIN32 |
|
9 |
-#define USE_WINDOWS_FILE |
|
10 |
-#endif |
|
11 |
-*/ |
|
12 |
- |
|
13 |
-#ifdef USE_WINDOWS_FILE |
|
14 |
-#include <windows.h> |
|
15 |
-#else |
|
16 |
-#include <stdio.h> |
|
17 |
-#endif |
|
18 |
- |
|
19 |
-#include "Types.h" |
|
20 |
- |
|
21 |
- |
|
22 |
-/* ---------- File ---------- */ |
|
23 |
- |
|
24 |
-typedef struct |
|
25 |
-{ |
|
26 |
- #ifdef USE_WINDOWS_FILE |
|
27 |
- HANDLE handle; |
|
28 |
- #else |
|
29 |
- FILE *file; |
|
30 |
- #endif |
|
31 |
-} CSzFile; |
|
32 |
- |
|
33 |
-void File_Construct(CSzFile *p); |
|
34 |
-WRes InFile_Open(CSzFile *p, const char *name); |
|
35 |
-WRes OutFile_Open(CSzFile *p, const char *name); |
|
36 |
-WRes File_Close(CSzFile *p); |
|
37 |
- |
|
38 |
-/* reads max(*size, remain file's size) bytes */ |
|
39 |
-WRes File_Read(CSzFile *p, void *data, size_t *size); |
|
40 |
- |
|
41 |
-/* writes *size bytes */ |
|
42 |
-WRes File_Write(CSzFile *p, const void *data, size_t *size); |
|
43 |
- |
|
44 |
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); |
|
45 |
-WRes File_GetLength(CSzFile *p, UInt64 *length); |
|
46 |
- |
|
47 |
- |
|
48 |
-/* ---------- FileInStream ---------- */ |
|
49 |
- |
|
50 |
-typedef struct |
|
51 |
-{ |
|
52 |
- ISeqInStream s; |
|
53 |
- CSzFile file; |
|
54 |
-} CFileSeqInStream; |
|
55 |
- |
|
56 |
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p); |
|
57 |
- |
|
58 |
- |
|
59 |
-typedef struct |
|
60 |
-{ |
|
61 |
- ISeekInStream s; |
|
62 |
- CSzFile file; |
|
63 |
-} CFileInStream; |
|
64 |
- |
|
65 |
-void FileInStream_CreateVTable(CFileInStream *p); |
|
66 |
- |
|
67 |
- |
|
68 |
-typedef struct |
|
69 |
-{ |
|
70 |
- ISeqOutStream s; |
|
71 |
- CSzFile file; |
|
72 |
-} CFileOutStream; |
|
73 |
- |
|
74 |
-void FileOutStream_CreateVTable(CFileOutStream *p); |
|
75 |
- |
|
76 |
-#endif |
|
1 |
+/* 7zFile.h -- File IO |
|
2 |
+2008-11-22 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_FILE_H |
|
5 |
+#define __7Z_FILE_H |
|
6 |
+ |
|
7 |
+/* aCaB -- do not use HANDLE on win32 |
|
8 |
+#ifdef _WIN32 |
|
9 |
+#define USE_WINDOWS_FILE |
|
10 |
+#endif |
|
11 |
+*/ |
|
12 |
+ |
|
13 |
+#ifdef USE_WINDOWS_FILE |
|
14 |
+#include <windows.h> |
|
15 |
+#else |
|
16 |
+#include <stdio.h> |
|
17 |
+#endif |
|
18 |
+ |
|
19 |
+#include "Types.h" |
|
20 |
+ |
|
21 |
+ |
|
22 |
+/* ---------- File ---------- */ |
|
23 |
+ |
|
24 |
+typedef struct |
|
25 |
+{ |
|
26 |
+ #ifdef USE_WINDOWS_FILE |
|
27 |
+ HANDLE handle; |
|
28 |
+ #else |
|
29 |
+ FILE *file; |
|
30 |
+ #endif |
|
31 |
+} CSzFile; |
|
32 |
+ |
|
33 |
+void File_Construct(CSzFile *p); |
|
34 |
+WRes InFile_Open(CSzFile *p, const char *name); |
|
35 |
+WRes OutFile_Open(CSzFile *p, const char *name); |
|
36 |
+WRes File_Close(CSzFile *p); |
|
37 |
+ |
|
38 |
+/* reads max(*size, remain file's size) bytes */ |
|
39 |
+WRes File_Read(CSzFile *p, void *data, size_t *size); |
|
40 |
+ |
|
41 |
+/* writes *size bytes */ |
|
42 |
+WRes File_Write(CSzFile *p, const void *data, size_t *size); |
|
43 |
+ |
|
44 |
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); |
|
45 |
+WRes File_GetLength(CSzFile *p, UInt64 *length); |
|
46 |
+ |
|
47 |
+ |
|
48 |
+/* ---------- FileInStream ---------- */ |
|
49 |
+ |
|
50 |
+typedef struct |
|
51 |
+{ |
|
52 |
+ ISeqInStream s; |
|
53 |
+ CSzFile file; |
|
54 |
+} CFileSeqInStream; |
|
55 |
+ |
|
56 |
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p); |
|
57 |
+ |
|
58 |
+ |
|
59 |
+typedef struct |
|
60 |
+{ |
|
61 |
+ ISeekInStream s; |
|
62 |
+ CSzFile file; |
|
63 |
+} CFileInStream; |
|
64 |
+ |
|
65 |
+void FileInStream_CreateVTable(CFileInStream *p); |
|
66 |
+ |
|
67 |
+ |
|
68 |
+typedef struct |
|
69 |
+{ |
|
70 |
+ ISeqOutStream s; |
|
71 |
+ CSzFile file; |
|
72 |
+} CFileOutStream; |
|
73 |
+ |
|
74 |
+void FileOutStream_CreateVTable(CFileOutStream *p); |
|
75 |
+ |
|
76 |
+#endif |
... | ... |
@@ -1,169 +1,169 @@ |
1 |
-/* 7zStream.c -- 7z Stream functions |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include <string.h> |
|
5 |
- |
|
6 |
-#include "Types.h" |
|
7 |
- |
|
8 |
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) |
|
9 |
-{ |
|
10 |
- while (size != 0) |
|
11 |
- { |
|
12 |
- size_t processed = size; |
|
13 |
- RINOK(stream->Read(stream, buf, &processed)); |
|
14 |
- if (processed == 0) |
|
15 |
- return errorType; |
|
16 |
- buf = (void *)((Byte *)buf + processed); |
|
17 |
- size -= processed; |
|
18 |
- } |
|
19 |
- return SZ_OK; |
|
20 |
-} |
|
21 |
- |
|
22 |
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) |
|
23 |
-{ |
|
24 |
- return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
25 |
-} |
|
26 |
- |
|
27 |
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) |
|
28 |
-{ |
|
29 |
- size_t processed = 1; |
|
30 |
- RINOK(stream->Read(stream, buf, &processed)); |
|
31 |
- return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; |
|
32 |
-} |
|
33 |
- |
|
34 |
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) |
|
35 |
-{ |
|
36 |
- Int64 t = offset; |
|
37 |
- return stream->Seek(stream, &t, SZ_SEEK_SET); |
|
38 |
-} |
|
39 |
- |
|
40 |
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) |
|
41 |
-{ |
|
42 |
- void *lookBuf; |
|
43 |
- if (*size == 0) |
|
44 |
- return SZ_OK; |
|
45 |
- RINOK(stream->Look(stream, &lookBuf, size)); |
|
46 |
- memcpy(buf, lookBuf, *size); |
|
47 |
- return stream->Skip(stream, *size); |
|
48 |
-} |
|
49 |
- |
|
50 |
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) |
|
51 |
-{ |
|
52 |
- while (size != 0) |
|
53 |
- { |
|
54 |
- size_t processed = size; |
|
55 |
- RINOK(stream->Read(stream, buf, &processed)); |
|
56 |
- if (processed == 0) |
|
57 |
- return errorType; |
|
58 |
- buf = (void *)((Byte *)buf + processed); |
|
59 |
- size -= processed; |
|
60 |
- } |
|
61 |
- return SZ_OK; |
|
62 |
-} |
|
63 |
- |
|
64 |
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) |
|
65 |
-{ |
|
66 |
- return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
67 |
-} |
|
68 |
- |
|
69 |
-static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) |
|
70 |
-{ |
|
71 |
- SRes res = SZ_OK; |
|
72 |
- CLookToRead *p = (CLookToRead *)pp; |
|
73 |
- size_t size2 = p->size - p->pos; |
|
74 |
- if (size2 == 0 && *size > 0) |
|
75 |
- { |
|
76 |
- p->pos = 0; |
|
77 |
- size2 = LookToRead_BUF_SIZE; |
|
78 |
- res = p->realStream->Read(p->realStream, p->buf, &size2); |
|
79 |
- p->size = size2; |
|
80 |
- } |
|
81 |
- if (size2 < *size) |
|
82 |
- *size = size2; |
|
83 |
- *buf = p->buf + p->pos; |
|
84 |
- return res; |
|
85 |
-} |
|
86 |
- |
|
87 |
-static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) |
|
88 |
-{ |
|
89 |
- SRes res = SZ_OK; |
|
90 |
- CLookToRead *p = (CLookToRead *)pp; |
|
91 |
- size_t size2 = p->size - p->pos; |
|
92 |
- if (size2 == 0 && *size > 0) |
|
93 |
- { |
|
94 |
- p->pos = 0; |
|
95 |
- if (*size > LookToRead_BUF_SIZE) |
|
96 |
- *size = LookToRead_BUF_SIZE; |
|
97 |
- res = p->realStream->Read(p->realStream, p->buf, size); |
|
98 |
- size2 = p->size = *size; |
|
99 |
- } |
|
100 |
- if (size2 < *size) |
|
101 |
- *size = size2; |
|
102 |
- *buf = p->buf + p->pos; |
|
103 |
- return res; |
|
104 |
-} |
|
105 |
- |
|
106 |
-static SRes LookToRead_Skip(void *pp, size_t offset) |
|
107 |
-{ |
|
108 |
- CLookToRead *p = (CLookToRead *)pp; |
|
109 |
- p->pos += offset; |
|
110 |
- return SZ_OK; |
|
111 |
-} |
|
112 |
- |
|
113 |
-static SRes LookToRead_Read(void *pp, void *buf, size_t *size) |
|
114 |
-{ |
|
115 |
- CLookToRead *p = (CLookToRead *)pp; |
|
116 |
- size_t rem = p->size - p->pos; |
|
117 |
- if (rem == 0) |
|
118 |
- return p->realStream->Read(p->realStream, buf, size); |
|
119 |
- if (rem > *size) |
|
120 |
- rem = *size; |
|
121 |
- memcpy(buf, p->buf + p->pos, rem); |
|
122 |
- p->pos += rem; |
|
123 |
- *size = rem; |
|
124 |
- return SZ_OK; |
|
125 |
-} |
|
126 |
- |
|
127 |
-static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
128 |
-{ |
|
129 |
- CLookToRead *p = (CLookToRead *)pp; |
|
130 |
- p->pos = p->size = 0; |
|
131 |
- return p->realStream->Seek(p->realStream, pos, origin); |
|
132 |
-} |
|
133 |
- |
|
134 |
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead) |
|
135 |
-{ |
|
136 |
- p->s.Look = lookahead ? |
|
137 |
- LookToRead_Look_Lookahead : |
|
138 |
- LookToRead_Look_Exact; |
|
139 |
- p->s.Skip = LookToRead_Skip; |
|
140 |
- p->s.Read = LookToRead_Read; |
|
141 |
- p->s.Seek = LookToRead_Seek; |
|
142 |
-} |
|
143 |
- |
|
144 |
-void LookToRead_Init(CLookToRead *p) |
|
145 |
-{ |
|
146 |
- p->pos = p->size = 0; |
|
147 |
-} |
|
148 |
- |
|
149 |
-static SRes SecToLook_Read(void *pp, void *buf, size_t *size) |
|
150 |
-{ |
|
151 |
- CSecToLook *p = (CSecToLook *)pp; |
|
152 |
- return LookInStream_LookRead(p->realStream, buf, size); |
|
153 |
-} |
|
154 |
- |
|
155 |
-void SecToLook_CreateVTable(CSecToLook *p) |
|
156 |
-{ |
|
157 |
- p->s.Read = SecToLook_Read; |
|
158 |
-} |
|
159 |
- |
|
160 |
-static SRes SecToRead_Read(void *pp, void *buf, size_t *size) |
|
161 |
-{ |
|
162 |
- CSecToRead *p = (CSecToRead *)pp; |
|
163 |
- return p->realStream->Read(p->realStream, buf, size); |
|
164 |
-} |
|
165 |
- |
|
166 |
-void SecToRead_CreateVTable(CSecToRead *p) |
|
167 |
-{ |
|
168 |
- p->s.Read = SecToRead_Read; |
|
169 |
-} |
|
1 |
+/* 7zStream.c -- 7z Stream functions |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include <string.h> |
|
5 |
+ |
|
6 |
+#include "Types.h" |
|
7 |
+ |
|
8 |
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) |
|
9 |
+{ |
|
10 |
+ while (size != 0) |
|
11 |
+ { |
|
12 |
+ size_t processed = size; |
|
13 |
+ RINOK(stream->Read(stream, buf, &processed)); |
|
14 |
+ if (processed == 0) |
|
15 |
+ return errorType; |
|
16 |
+ buf = (void *)((Byte *)buf + processed); |
|
17 |
+ size -= processed; |
|
18 |
+ } |
|
19 |
+ return SZ_OK; |
|
20 |
+} |
|
21 |
+ |
|
22 |
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) |
|
23 |
+{ |
|
24 |
+ return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
25 |
+} |
|
26 |
+ |
|
27 |
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) |
|
28 |
+{ |
|
29 |
+ size_t processed = 1; |
|
30 |
+ RINOK(stream->Read(stream, buf, &processed)); |
|
31 |
+ return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; |
|
32 |
+} |
|
33 |
+ |
|
34 |
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) |
|
35 |
+{ |
|
36 |
+ Int64 t = offset; |
|
37 |
+ return stream->Seek(stream, &t, SZ_SEEK_SET); |
|
38 |
+} |
|
39 |
+ |
|
40 |
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) |
|
41 |
+{ |
|
42 |
+ void *lookBuf; |
|
43 |
+ if (*size == 0) |
|
44 |
+ return SZ_OK; |
|
45 |
+ RINOK(stream->Look(stream, &lookBuf, size)); |
|
46 |
+ memcpy(buf, lookBuf, *size); |
|
47 |
+ return stream->Skip(stream, *size); |
|
48 |
+} |
|
49 |
+ |
|
50 |
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) |
|
51 |
+{ |
|
52 |
+ while (size != 0) |
|
53 |
+ { |
|
54 |
+ size_t processed = size; |
|
55 |
+ RINOK(stream->Read(stream, buf, &processed)); |
|
56 |
+ if (processed == 0) |
|
57 |
+ return errorType; |
|
58 |
+ buf = (void *)((Byte *)buf + processed); |
|
59 |
+ size -= processed; |
|
60 |
+ } |
|
61 |
+ return SZ_OK; |
|
62 |
+} |
|
63 |
+ |
|
64 |
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) |
|
65 |
+{ |
|
66 |
+ return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
67 |
+} |
|
68 |
+ |
|
69 |
+static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) |
|
70 |
+{ |
|
71 |
+ SRes res = SZ_OK; |
|
72 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
73 |
+ size_t size2 = p->size - p->pos; |
|
74 |
+ if (size2 == 0 && *size > 0) |
|
75 |
+ { |
|
76 |
+ p->pos = 0; |
|
77 |
+ size2 = LookToRead_BUF_SIZE; |
|
78 |
+ res = p->realStream->Read(p->realStream, p->buf, &size2); |
|
79 |
+ p->size = size2; |
|
80 |
+ } |
|
81 |
+ if (size2 < *size) |
|
82 |
+ *size = size2; |
|
83 |
+ *buf = p->buf + p->pos; |
|
84 |
+ return res; |
|
85 |
+} |
|
86 |
+ |
|
87 |
+static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) |
|
88 |
+{ |
|
89 |
+ SRes res = SZ_OK; |
|
90 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
91 |
+ size_t size2 = p->size - p->pos; |
|
92 |
+ if (size2 == 0 && *size > 0) |
|
93 |
+ { |
|
94 |
+ p->pos = 0; |
|
95 |
+ if (*size > LookToRead_BUF_SIZE) |
|
96 |
+ *size = LookToRead_BUF_SIZE; |
|
97 |
+ res = p->realStream->Read(p->realStream, p->buf, size); |
|
98 |
+ size2 = p->size = *size; |
|
99 |
+ } |
|
100 |
+ if (size2 < *size) |
|
101 |
+ *size = size2; |
|
102 |
+ *buf = p->buf + p->pos; |
|
103 |
+ return res; |
|
104 |
+} |
|
105 |
+ |
|
106 |
+static SRes LookToRead_Skip(void *pp, size_t offset) |
|
107 |
+{ |
|
108 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
109 |
+ p->pos += offset; |
|
110 |
+ return SZ_OK; |
|
111 |
+} |
|
112 |
+ |
|
113 |
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size) |
|
114 |
+{ |
|
115 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
116 |
+ size_t rem = p->size - p->pos; |
|
117 |
+ if (rem == 0) |
|
118 |
+ return p->realStream->Read(p->realStream, buf, size); |
|
119 |
+ if (rem > *size) |
|
120 |
+ rem = *size; |
|
121 |
+ memcpy(buf, p->buf + p->pos, rem); |
|
122 |
+ p->pos += rem; |
|
123 |
+ *size = rem; |
|
124 |
+ return SZ_OK; |
|
125 |
+} |
|
126 |
+ |
|
127 |
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
128 |
+{ |
|
129 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
130 |
+ p->pos = p->size = 0; |
|
131 |
+ return p->realStream->Seek(p->realStream, pos, origin); |
|
132 |
+} |
|
133 |
+ |
|
134 |
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead) |
|
135 |
+{ |
|
136 |
+ p->s.Look = lookahead ? |
|
137 |
+ LookToRead_Look_Lookahead : |
|
138 |
+ LookToRead_Look_Exact; |
|
139 |
+ p->s.Skip = LookToRead_Skip; |
|
140 |
+ p->s.Read = LookToRead_Read; |
|
141 |
+ p->s.Seek = LookToRead_Seek; |
|
142 |
+} |
|
143 |
+ |
|
144 |
+void LookToRead_Init(CLookToRead *p) |
|
145 |
+{ |
|
146 |
+ p->pos = p->size = 0; |
|
147 |
+} |
|
148 |
+ |
|
149 |
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size) |
|
150 |
+{ |
|
151 |
+ CSecToLook *p = (CSecToLook *)pp; |
|
152 |
+ return LookInStream_LookRead(p->realStream, buf, size); |
|
153 |
+} |
|
154 |
+ |
|
155 |
+void SecToLook_CreateVTable(CSecToLook *p) |
|
156 |
+{ |
|
157 |
+ p->s.Read = SecToLook_Read; |
|
158 |
+} |
|
159 |
+ |
|
160 |
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size) |
|
161 |
+{ |
|
162 |
+ CSecToRead *p = (CSecToRead *)pp; |
|
163 |
+ return p->realStream->Read(p->realStream, buf, size); |
|
164 |
+} |
|
165 |
+ |
|
166 |
+void SecToRead_CreateVTable(CSecToRead *p) |
|
167 |
+{ |
|
168 |
+ p->s.Read = SecToRead_Read; |
|
169 |
+} |
... | ... |
@@ -1,254 +1,254 @@ |
1 |
-/* 7zDecode.c -- Decoding from 7z folder |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include <string.h> |
|
5 |
- |
|
6 |
-#include "../../Bcj2.h" |
|
7 |
-#include "../../Bra.h" |
|
8 |
-#include "../../LzmaDec.h" |
|
9 |
-#include "7zDecode.h" |
|
10 |
- |
|
11 |
-#define k_Copy 0 |
|
12 |
-#define k_LZMA 0x30101 |
|
13 |
-#define k_BCJ 0x03030103 |
|
14 |
-#define k_BCJ2 0x0303011B |
|
15 |
- |
|
16 |
-static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, |
|
17 |
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) |
|
18 |
-{ |
|
19 |
- CLzmaDec state; |
|
20 |
- SRes res = SZ_OK; |
|
21 |
- |
|
22 |
- LzmaDec_Construct(&state); |
|
23 |
- RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); |
|
24 |
- state.dic = outBuffer; |
|
25 |
- state.dicBufSize = outSize; |
|
26 |
- LzmaDec_Init(&state); |
|
27 |
- |
|
28 |
- for (;;) |
|
29 |
- { |
|
30 |
- Byte *inBuf = NULL; |
|
31 |
- size_t lookahead = (1 << 18); |
|
32 |
- if (lookahead > inSize) |
|
33 |
- lookahead = (size_t)inSize; |
|
34 |
- res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); |
|
35 |
- if (res != SZ_OK) |
|
36 |
- break; |
|
37 |
- |
|
38 |
- { |
|
39 |
- SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; |
|
40 |
- ELzmaStatus status; |
|
41 |
- res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); |
|
42 |
- lookahead -= inProcessed; |
|
43 |
- inSize -= inProcessed; |
|
44 |
- if (res != SZ_OK) |
|
45 |
- break; |
|
46 |
- if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) |
|
47 |
- { |
|
48 |
- if (state.dicBufSize != outSize || lookahead != 0 || |
|
49 |
- (status != LZMA_STATUS_FINISHED_WITH_MARK && |
|
50 |
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) |
|
51 |
- res = SZ_ERROR_DATA; |
|
52 |
- break; |
|
53 |
- } |
|
54 |
- res = inStream->Skip((void *)inStream, inProcessed); |
|
55 |
- if (res != SZ_OK) |
|
56 |
- break; |
|
57 |
- } |
|
58 |
- } |
|
59 |
- |
|
60 |
- LzmaDec_FreeProbs(&state, allocMain); |
|
61 |
- return res; |
|
62 |
-} |
|
63 |
- |
|
64 |
-static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) |
|
65 |
-{ |
|
66 |
- while (inSize > 0) |
|
67 |
- { |
|
68 |
- void *inBuf; |
|
69 |
- size_t curSize = (1 << 18); |
|
70 |
- if (curSize > inSize) |
|
71 |
- curSize = (size_t)inSize; |
|
72 |
- RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); |
|
73 |
- if (curSize == 0) |
|
74 |
- return SZ_ERROR_INPUT_EOF; |
|
75 |
- memcpy(outBuffer, inBuf, curSize); |
|
76 |
- outBuffer += curSize; |
|
77 |
- inSize -= curSize; |
|
78 |
- RINOK(inStream->Skip((void *)inStream, curSize)); |
|
79 |
- } |
|
80 |
- return SZ_OK; |
|
81 |
-} |
|
82 |
- |
|
83 |
-#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) |
|
84 |
-#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) |
|
85 |
-#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) |
|
86 |
-#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) |
|
87 |
- |
|
88 |
-SRes CheckSupportedFolder(const CSzFolder *f) |
|
89 |
-{ |
|
90 |
- if (f->NumCoders < 1 || f->NumCoders > 4) |
|
91 |
- return SZ_ERROR_UNSUPPORTED; |
|
92 |
- if (IS_UNSUPPORTED_CODER(f->Coders[0])) |
|
93 |
- return SZ_ERROR_UNSUPPORTED; |
|
94 |
- if (f->NumCoders == 1) |
|
95 |
- { |
|
96 |
- if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) |
|
97 |
- return SZ_ERROR_UNSUPPORTED; |
|
98 |
- return SZ_OK; |
|
99 |
- } |
|
100 |
- if (f->NumCoders == 2) |
|
101 |
- { |
|
102 |
- if (IS_NO_BCJ(f->Coders[1]) || |
|
103 |
- f->NumPackStreams != 1 || f->PackStreams[0] != 0 || |
|
104 |
- f->NumBindPairs != 1 || |
|
105 |
- f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) |
|
106 |
- return SZ_ERROR_UNSUPPORTED; |
|
107 |
- return SZ_OK; |
|
108 |
- } |
|
109 |
- if (f->NumCoders == 4) |
|
110 |
- { |
|
111 |
- if (IS_UNSUPPORTED_CODER(f->Coders[1]) || |
|
112 |
- IS_UNSUPPORTED_CODER(f->Coders[2]) || |
|
113 |
- IS_NO_BCJ2(f->Coders[3])) |
|
114 |
- return SZ_ERROR_UNSUPPORTED; |
|
115 |
- if (f->NumPackStreams != 4 || |
|
116 |
- f->PackStreams[0] != 2 || |
|
117 |
- f->PackStreams[1] != 6 || |
|
118 |
- f->PackStreams[2] != 1 || |
|
119 |
- f->PackStreams[3] != 0 || |
|
120 |
- f->NumBindPairs != 3 || |
|
121 |
- f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || |
|
122 |
- f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || |
|
123 |
- f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) |
|
124 |
- return SZ_ERROR_UNSUPPORTED; |
|
125 |
- return SZ_OK; |
|
126 |
- } |
|
127 |
- return SZ_ERROR_UNSUPPORTED; |
|
128 |
-} |
|
129 |
- |
|
130 |
-UInt64 GetSum(const UInt64 *values, UInt32 index) |
|
131 |
-{ |
|
132 |
- UInt64 sum = 0; |
|
133 |
- UInt32 i; |
|
134 |
- for (i = 0; i < index; i++) |
|
135 |
- sum += values[i]; |
|
136 |
- return sum; |
|
137 |
-} |
|
138 |
- |
|
139 |
-SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, |
|
140 |
- ILookInStream *inStream, UInt64 startPos, |
|
141 |
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, |
|
142 |
- Byte *tempBuf[]) |
|
143 |
-{ |
|
144 |
- UInt32 ci; |
|
145 |
- SizeT tempSizes[3] = { 0, 0, 0}; |
|
146 |
- SizeT tempSize3 = 0; |
|
147 |
- Byte *tempBuf3 = 0; |
|
148 |
- |
|
149 |
- RINOK(CheckSupportedFolder(folder)); |
|
150 |
- |
|
151 |
- for (ci = 0; ci < folder->NumCoders; ci++) |
|
152 |
- { |
|
153 |
- CSzCoderInfo *coder = &folder->Coders[ci]; |
|
154 |
- |
|
155 |
- if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) |
|
156 |
- { |
|
157 |
- UInt32 si = 0; |
|
158 |
- UInt64 offset; |
|
159 |
- UInt64 inSize; |
|
160 |
- Byte *outBufCur = outBuffer; |
|
161 |
- SizeT outSizeCur = outSize; |
|
162 |
- if (folder->NumCoders == 4) |
|
163 |
- { |
|
164 |
- UInt32 indices[] = { 3, 2, 0 }; |
|
165 |
- UInt64 unpackSize = folder->UnpackSizes[ci]; |
|
166 |
- si = indices[ci]; |
|
167 |
- if (ci < 2) |
|
168 |
- { |
|
169 |
- Byte *temp; |
|
170 |
- outSizeCur = (SizeT)unpackSize; |
|
171 |
- if (outSizeCur != unpackSize) |
|
172 |
- return SZ_ERROR_MEM; |
|
173 |
- temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); |
|
174 |
- if (temp == 0 && outSizeCur != 0) |
|
175 |
- return SZ_ERROR_MEM; |
|
176 |
- outBufCur = tempBuf[1 - ci] = temp; |
|
177 |
- tempSizes[1 - ci] = outSizeCur; |
|
178 |
- } |
|
179 |
- else if (ci == 2) |
|
180 |
- { |
|
181 |
- if (unpackSize > outSize) /* check it */ |
|
182 |
- return SZ_ERROR_PARAM; |
|
183 |
- tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); |
|
184 |
- tempSize3 = outSizeCur = (SizeT)unpackSize; |
|
185 |
- } |
|
186 |
- else |
|
187 |
- return SZ_ERROR_UNSUPPORTED; |
|
188 |
- } |
|
189 |
- offset = GetSum(packSizes, si); |
|
190 |
- inSize = packSizes[si]; |
|
191 |
- RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
192 |
- |
|
193 |
- if (coder->MethodID == k_Copy) |
|
194 |
- { |
|
195 |
- if (inSize != outSizeCur) /* check it */ |
|
196 |
- return SZ_ERROR_DATA; |
|
197 |
- RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); |
|
198 |
- } |
|
199 |
- else |
|
200 |
- { |
|
201 |
- RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
|
202 |
- } |
|
203 |
- } |
|
204 |
- else if (coder->MethodID == k_BCJ) |
|
205 |
- { |
|
206 |
- UInt32 state; |
|
207 |
- if (ci != 1) |
|
208 |
- return SZ_ERROR_UNSUPPORTED; |
|
209 |
- x86_Convert_Init(state); |
|
210 |
- x86_Convert(outBuffer, outSize, 0, &state, 0); |
|
211 |
- } |
|
212 |
- else if (coder->MethodID == k_BCJ2) |
|
213 |
- { |
|
214 |
- UInt64 offset = GetSum(packSizes, 1); |
|
215 |
- UInt64 s3Size = packSizes[1]; |
|
216 |
- SRes res; |
|
217 |
- if (ci != 3) |
|
218 |
- return SZ_ERROR_UNSUPPORTED; |
|
219 |
- RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
220 |
- tempSizes[2] = (SizeT)s3Size; |
|
221 |
- if (tempSizes[2] != s3Size) |
|
222 |
- return SZ_ERROR_MEM; |
|
223 |
- tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); |
|
224 |
- if (tempBuf[2] == 0 && tempSizes[2] != 0) |
|
225 |
- return SZ_ERROR_MEM; |
|
226 |
- res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); |
|
227 |
- RINOK(res) |
|
228 |
- |
|
229 |
- res = Bcj2_Decode( |
|
230 |
- tempBuf3, tempSize3, |
|
231 |
- tempBuf[0], tempSizes[0], |
|
232 |
- tempBuf[1], tempSizes[1], |
|
233 |
- tempBuf[2], tempSizes[2], |
|
234 |
- outBuffer, outSize); |
|
235 |
- RINOK(res) |
|
236 |
- } |
|
237 |
- else |
|
238 |
- return SZ_ERROR_UNSUPPORTED; |
|
239 |
- } |
|
240 |
- return SZ_OK; |
|
241 |
-} |
|
242 |
- |
|
243 |
-SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, |
|
244 |
- ILookInStream *inStream, UInt64 startPos, |
|
245 |
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) |
|
246 |
-{ |
|
247 |
- Byte *tempBuf[3] = { 0, 0, 0}; |
|
248 |
- int i; |
|
249 |
- SRes res = SzDecode2(packSizes, folder, inStream, startPos, |
|
250 |
- outBuffer, (SizeT)outSize, allocMain, tempBuf); |
|
251 |
- for (i = 0; i < 3; i++) |
|
252 |
- IAlloc_Free(allocMain, tempBuf[i]); |
|
253 |
- return res; |
|
254 |
-} |
|
1 |
+/* 7zDecode.c -- Decoding from 7z folder |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include <string.h> |
|
5 |
+ |
|
6 |
+#include "../../Bcj2.h" |
|
7 |
+#include "../../Bra.h" |
|
8 |
+#include "../../LzmaDec.h" |
|
9 |
+#include "7zDecode.h" |
|
10 |
+ |
|
11 |
+#define k_Copy 0 |
|
12 |
+#define k_LZMA 0x30101 |
|
13 |
+#define k_BCJ 0x03030103 |
|
14 |
+#define k_BCJ2 0x0303011B |
|
15 |
+ |
|
16 |
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, |
|
17 |
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) |
|
18 |
+{ |
|
19 |
+ CLzmaDec state; |
|
20 |
+ SRes res = SZ_OK; |
|
21 |
+ |
|
22 |
+ LzmaDec_Construct(&state); |
|
23 |
+ RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); |
|
24 |
+ state.dic = outBuffer; |
|
25 |
+ state.dicBufSize = outSize; |
|
26 |
+ LzmaDec_Init(&state); |
|
27 |
+ |
|
28 |
+ for (;;) |
|
29 |
+ { |
|
30 |
+ Byte *inBuf = NULL; |
|
31 |
+ size_t lookahead = (1 << 18); |
|
32 |
+ if (lookahead > inSize) |
|
33 |
+ lookahead = (size_t)inSize; |
|
34 |
+ res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); |
|
35 |
+ if (res != SZ_OK) |
|
36 |
+ break; |
|
37 |
+ |
|
38 |
+ { |
|
39 |
+ SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; |
|
40 |
+ ELzmaStatus status; |
|
41 |
+ res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); |
|
42 |
+ lookahead -= inProcessed; |
|
43 |
+ inSize -= inProcessed; |
|
44 |
+ if (res != SZ_OK) |
|
45 |
+ break; |
|
46 |
+ if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) |
|
47 |
+ { |
|
48 |
+ if (state.dicBufSize != outSize || lookahead != 0 || |
|
49 |
+ (status != LZMA_STATUS_FINISHED_WITH_MARK && |
|
50 |
+ status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) |
|
51 |
+ res = SZ_ERROR_DATA; |
|
52 |
+ break; |
|
53 |
+ } |
|
54 |
+ res = inStream->Skip((void *)inStream, inProcessed); |
|
55 |
+ if (res != SZ_OK) |
|
56 |
+ break; |
|
57 |
+ } |
|
58 |
+ } |
|
59 |
+ |
|
60 |
+ LzmaDec_FreeProbs(&state, allocMain); |
|
61 |
+ return res; |
|
62 |
+} |
|
63 |
+ |
|
64 |
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) |
|
65 |
+{ |
|
66 |
+ while (inSize > 0) |
|
67 |
+ { |
|
68 |
+ void *inBuf; |
|
69 |
+ size_t curSize = (1 << 18); |
|
70 |
+ if (curSize > inSize) |
|
71 |
+ curSize = (size_t)inSize; |
|
72 |
+ RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); |
|
73 |
+ if (curSize == 0) |
|
74 |
+ return SZ_ERROR_INPUT_EOF; |
|
75 |
+ memcpy(outBuffer, inBuf, curSize); |
|
76 |
+ outBuffer += curSize; |
|
77 |
+ inSize -= curSize; |
|
78 |
+ RINOK(inStream->Skip((void *)inStream, curSize)); |
|
79 |
+ } |
|
80 |
+ return SZ_OK; |
|
81 |
+} |
|
82 |
+ |
|
83 |
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) |
|
84 |
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) |
|
85 |
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) |
|
86 |
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) |
|
87 |
+ |
|
88 |
+SRes CheckSupportedFolder(const CSzFolder *f) |
|
89 |
+{ |
|
90 |
+ if (f->NumCoders < 1 || f->NumCoders > 4) |
|
91 |
+ return SZ_ERROR_UNSUPPORTED; |
|
92 |
+ if (IS_UNSUPPORTED_CODER(f->Coders[0])) |
|
93 |
+ return SZ_ERROR_UNSUPPORTED; |
|
94 |
+ if (f->NumCoders == 1) |
|
95 |
+ { |
|
96 |
+ if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) |
|
97 |
+ return SZ_ERROR_UNSUPPORTED; |
|
98 |
+ return SZ_OK; |
|
99 |
+ } |
|
100 |
+ if (f->NumCoders == 2) |
|
101 |
+ { |
|
102 |
+ if (IS_NO_BCJ(f->Coders[1]) || |
|
103 |
+ f->NumPackStreams != 1 || f->PackStreams[0] != 0 || |
|
104 |
+ f->NumBindPairs != 1 || |
|
105 |
+ f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) |
|
106 |
+ return SZ_ERROR_UNSUPPORTED; |
|
107 |
+ return SZ_OK; |
|
108 |
+ } |
|
109 |
+ if (f->NumCoders == 4) |
|
110 |
+ { |
|
111 |
+ if (IS_UNSUPPORTED_CODER(f->Coders[1]) || |
|
112 |
+ IS_UNSUPPORTED_CODER(f->Coders[2]) || |
|
113 |
+ IS_NO_BCJ2(f->Coders[3])) |
|
114 |
+ return SZ_ERROR_UNSUPPORTED; |
|
115 |
+ if (f->NumPackStreams != 4 || |
|
116 |
+ f->PackStreams[0] != 2 || |
|
117 |
+ f->PackStreams[1] != 6 || |
|
118 |
+ f->PackStreams[2] != 1 || |
|
119 |
+ f->PackStreams[3] != 0 || |
|
120 |
+ f->NumBindPairs != 3 || |
|
121 |
+ f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || |
|
122 |
+ f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || |
|
123 |
+ f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) |
|
124 |
+ return SZ_ERROR_UNSUPPORTED; |
|
125 |
+ return SZ_OK; |
|
126 |
+ } |
|
127 |
+ return SZ_ERROR_UNSUPPORTED; |
|
128 |
+} |
|
129 |
+ |
|
130 |
+UInt64 GetSum(const UInt64 *values, UInt32 index) |
|
131 |
+{ |
|
132 |
+ UInt64 sum = 0; |
|
133 |
+ UInt32 i; |
|
134 |
+ for (i = 0; i < index; i++) |
|
135 |
+ sum += values[i]; |
|
136 |
+ return sum; |
|
137 |
+} |
|
138 |
+ |
|
139 |
+SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, |
|
140 |
+ ILookInStream *inStream, UInt64 startPos, |
|
141 |
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, |
|
142 |
+ Byte *tempBuf[]) |
|
143 |
+{ |
|
144 |
+ UInt32 ci; |
|
145 |
+ SizeT tempSizes[3] = { 0, 0, 0}; |
|
146 |
+ SizeT tempSize3 = 0; |
|
147 |
+ Byte *tempBuf3 = 0; |
|
148 |
+ |
|
149 |
+ RINOK(CheckSupportedFolder(folder)); |
|
150 |
+ |
|
151 |
+ for (ci = 0; ci < folder->NumCoders; ci++) |
|
152 |
+ { |
|
153 |
+ CSzCoderInfo *coder = &folder->Coders[ci]; |
|
154 |
+ |
|
155 |
+ if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) |
|
156 |
+ { |
|
157 |
+ UInt32 si = 0; |
|
158 |
+ UInt64 offset; |
|
159 |
+ UInt64 inSize; |
|
160 |
+ Byte *outBufCur = outBuffer; |
|
161 |
+ SizeT outSizeCur = outSize; |
|
162 |
+ if (folder->NumCoders == 4) |
|
163 |
+ { |
|
164 |
+ UInt32 indices[] = { 3, 2, 0 }; |
|
165 |
+ UInt64 unpackSize = folder->UnpackSizes[ci]; |
|
166 |
+ si = indices[ci]; |
|
167 |
+ if (ci < 2) |
|
168 |
+ { |
|
169 |
+ Byte *temp; |
|
170 |
+ outSizeCur = (SizeT)unpackSize; |
|
171 |
+ if (outSizeCur != unpackSize) |
|
172 |
+ return SZ_ERROR_MEM; |
|
173 |
+ temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); |
|
174 |
+ if (temp == 0 && outSizeCur != 0) |
|
175 |
+ return SZ_ERROR_MEM; |
|
176 |
+ outBufCur = tempBuf[1 - ci] = temp; |
|
177 |
+ tempSizes[1 - ci] = outSizeCur; |
|
178 |
+ } |
|
179 |
+ else if (ci == 2) |
|
180 |
+ { |
|
181 |
+ if (unpackSize > outSize) /* check it */ |
|
182 |
+ return SZ_ERROR_PARAM; |
|
183 |
+ tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); |
|
184 |
+ tempSize3 = outSizeCur = (SizeT)unpackSize; |
|
185 |
+ } |
|
186 |
+ else |
|
187 |
+ return SZ_ERROR_UNSUPPORTED; |
|
188 |
+ } |
|
189 |
+ offset = GetSum(packSizes, si); |
|
190 |
+ inSize = packSizes[si]; |
|
191 |
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
192 |
+ |
|
193 |
+ if (coder->MethodID == k_Copy) |
|
194 |
+ { |
|
195 |
+ if (inSize != outSizeCur) /* check it */ |
|
196 |
+ return SZ_ERROR_DATA; |
|
197 |
+ RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); |
|
198 |
+ } |
|
199 |
+ else |
|
200 |
+ { |
|
201 |
+ RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
|
202 |
+ } |
|
203 |
+ } |
|
204 |
+ else if (coder->MethodID == k_BCJ) |
|
205 |
+ { |
|
206 |
+ UInt32 state; |
|
207 |
+ if (ci != 1) |
|
208 |
+ return SZ_ERROR_UNSUPPORTED; |
|
209 |
+ x86_Convert_Init(state); |
|
210 |
+ x86_Convert(outBuffer, outSize, 0, &state, 0); |
|
211 |
+ } |
|
212 |
+ else if (coder->MethodID == k_BCJ2) |
|
213 |
+ { |
|
214 |
+ UInt64 offset = GetSum(packSizes, 1); |
|
215 |
+ UInt64 s3Size = packSizes[1]; |
|
216 |
+ SRes res; |
|
217 |
+ if (ci != 3) |
|
218 |
+ return SZ_ERROR_UNSUPPORTED; |
|
219 |
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
220 |
+ tempSizes[2] = (SizeT)s3Size; |
|
221 |
+ if (tempSizes[2] != s3Size) |
|
222 |
+ return SZ_ERROR_MEM; |
|
223 |
+ tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); |
|
224 |
+ if (tempBuf[2] == 0 && tempSizes[2] != 0) |
|
225 |
+ return SZ_ERROR_MEM; |
|
226 |
+ res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); |
|
227 |
+ RINOK(res) |
|
228 |
+ |
|
229 |
+ res = Bcj2_Decode( |
|
230 |
+ tempBuf3, tempSize3, |
|
231 |
+ tempBuf[0], tempSizes[0], |
|
232 |
+ tempBuf[1], tempSizes[1], |
|
233 |
+ tempBuf[2], tempSizes[2], |
|
234 |
+ outBuffer, outSize); |
|
235 |
+ RINOK(res) |
|
236 |
+ } |
|
237 |
+ else |
|
238 |
+ return SZ_ERROR_UNSUPPORTED; |
|
239 |
+ } |
|
240 |
+ return SZ_OK; |
|
241 |
+} |
|
242 |
+ |
|
243 |
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, |
|
244 |
+ ILookInStream *inStream, UInt64 startPos, |
|
245 |
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) |
|
246 |
+{ |
|
247 |
+ Byte *tempBuf[3] = { 0, 0, 0}; |
|
248 |
+ int i; |
|
249 |
+ SRes res = SzDecode2(packSizes, folder, inStream, startPos, |
|
250 |
+ outBuffer, (SizeT)outSize, allocMain, tempBuf); |
|
251 |
+ for (i = 0; i < 3; i++) |
|
252 |
+ IAlloc_Free(allocMain, tempBuf[i]); |
|
253 |
+ return res; |
|
254 |
+} |
... | ... |
@@ -1,13 +1,13 @@ |
1 |
-/* 7zDecode.h -- Decoding from 7z folder |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_DECODE_H |
|
5 |
-#define __7Z_DECODE_H |
|
6 |
- |
|
7 |
-#include "7zItem.h" |
|
8 |
- |
|
9 |
-SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, |
|
10 |
- ILookInStream *stream, UInt64 startPos, |
|
11 |
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); |
|
12 |
- |
|
13 |
-#endif |
|
1 |
+/* 7zDecode.h -- Decoding from 7z folder |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_DECODE_H |
|
5 |
+#define __7Z_DECODE_H |
|
6 |
+ |
|
7 |
+#include "7zItem.h" |
|
8 |
+ |
|
9 |
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, |
|
10 |
+ ILookInStream *stream, UInt64 startPos, |
|
11 |
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); |
|
12 |
+ |
|
13 |
+#endif |
... | ... |
@@ -1,93 +1,93 @@ |
1 |
-/* 7zExtract.c -- Extracting from 7z archive |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "../../7zCrc.h" |
|
5 |
-#include "7zDecode.h" |
|
6 |
-#include "7zExtract.h" |
|
7 |
- |
|
8 |
-SRes SzAr_Extract( |
|
9 |
- const CSzArEx *p, |
|
10 |
- ILookInStream *inStream, |
|
11 |
- UInt32 fileIndex, |
|
12 |
- UInt32 *blockIndex, |
|
13 |
- Byte **outBuffer, |
|
14 |
- size_t *outBufferSize, |
|
15 |
- size_t *offset, |
|
16 |
- size_t *outSizeProcessed, |
|
17 |
- ISzAlloc *allocMain, |
|
18 |
- ISzAlloc *allocTemp) |
|
19 |
-{ |
|
20 |
- UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; |
|
21 |
- SRes res = SZ_OK; |
|
22 |
- *offset = 0; |
|
23 |
- *outSizeProcessed = 0; |
|
24 |
- if (folderIndex == (UInt32)-1) |
|
25 |
- { |
|
26 |
- IAlloc_Free(allocMain, *outBuffer); |
|
27 |
- *blockIndex = folderIndex; |
|
28 |
- *outBuffer = 0; |
|
29 |
- *outBufferSize = 0; |
|
30 |
- return SZ_OK; |
|
31 |
- } |
|
32 |
- |
|
33 |
- if (*outBuffer == 0 || *blockIndex != folderIndex) |
|
34 |
- { |
|
35 |
- CSzFolder *folder = p->db.Folders + folderIndex; |
|
36 |
- UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); |
|
37 |
- size_t unpackSize = (size_t)unpackSizeSpec; |
|
38 |
- UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); |
|
39 |
- |
|
40 |
- if (unpackSize != unpackSizeSpec) |
|
41 |
- return SZ_ERROR_MEM; |
|
42 |
- *blockIndex = folderIndex; |
|
43 |
- IAlloc_Free(allocMain, *outBuffer); |
|
44 |
- *outBuffer = 0; |
|
45 |
- |
|
46 |
- RINOK(LookInStream_SeekTo(inStream, startOffset)); |
|
47 |
- |
|
48 |
- if (res == SZ_OK) |
|
49 |
- { |
|
50 |
- *outBufferSize = unpackSize; |
|
51 |
- if (unpackSize != 0) |
|
52 |
- { |
|
53 |
- *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); |
|
54 |
- if (*outBuffer == 0) |
|
55 |
- res = SZ_ERROR_MEM; |
|
56 |
- } |
|
57 |
- if (res == SZ_OK) |
|
58 |
- { |
|
59 |
- res = SzDecode(p->db.PackSizes + |
|
60 |
- p->FolderStartPackStreamIndex[folderIndex], folder, |
|
61 |
- inStream, startOffset, |
|
62 |
- *outBuffer, unpackSize, allocTemp); |
|
63 |
- if (res == SZ_OK) |
|
64 |
- { |
|
65 |
- if (folder->UnpackCRCDefined) |
|
66 |
- { |
|
67 |
- if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) |
|
68 |
- res = SZ_ERROR_CRC; |
|
69 |
- } |
|
70 |
- } |
|
71 |
- } |
|
72 |
- } |
|
73 |
- } |
|
74 |
- if (res == SZ_OK) |
|
75 |
- { |
|
76 |
- UInt32 i; |
|
77 |
- CSzFileItem *fileItem = p->db.Files + fileIndex; |
|
78 |
- *offset = 0; |
|
79 |
- for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) |
|
80 |
- *offset += (UInt32)p->db.Files[i].Size; |
|
81 |
- *outSizeProcessed = (size_t)fileItem->Size; |
|
82 |
- if (*offset + *outSizeProcessed > *outBufferSize) |
|
83 |
- return SZ_ERROR_FAIL; |
|
84 |
- { |
|
85 |
- if (fileItem->FileCRCDefined) |
|
86 |
- { |
|
87 |
- if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) |
|
88 |
- res = SZ_ERROR_CRC; |
|
89 |
- } |
|
90 |
- } |
|
91 |
- } |
|
92 |
- return res; |
|
93 |
-} |
|
1 |
+/* 7zExtract.c -- Extracting from 7z archive |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "../../7zCrc.h" |
|
5 |
+#include "7zDecode.h" |
|
6 |
+#include "7zExtract.h" |
|
7 |
+ |
|
8 |
+SRes SzAr_Extract( |
|
9 |
+ const CSzArEx *p, |
|
10 |
+ ILookInStream *inStream, |
|
11 |
+ UInt32 fileIndex, |
|
12 |
+ UInt32 *blockIndex, |
|
13 |
+ Byte **outBuffer, |
|
14 |
+ size_t *outBufferSize, |
|
15 |
+ size_t *offset, |
|
16 |
+ size_t *outSizeProcessed, |
|
17 |
+ ISzAlloc *allocMain, |
|
18 |
+ ISzAlloc *allocTemp) |
|
19 |
+{ |
|
20 |
+ UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; |
|
21 |
+ SRes res = SZ_OK; |
|
22 |
+ *offset = 0; |
|
23 |
+ *outSizeProcessed = 0; |
|
24 |
+ if (folderIndex == (UInt32)-1) |
|
25 |
+ { |
|
26 |
+ IAlloc_Free(allocMain, *outBuffer); |
|
27 |
+ *blockIndex = folderIndex; |
|
28 |
+ *outBuffer = 0; |
|
29 |
+ *outBufferSize = 0; |
|
30 |
+ return SZ_OK; |
|
31 |
+ } |
|
32 |
+ |
|
33 |
+ if (*outBuffer == 0 || *blockIndex != folderIndex) |
|
34 |
+ { |
|
35 |
+ CSzFolder *folder = p->db.Folders + folderIndex; |
|
36 |
+ UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); |
|
37 |
+ size_t unpackSize = (size_t)unpackSizeSpec; |
|
38 |
+ UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); |
|
39 |
+ |
|
40 |
+ if (unpackSize != unpackSizeSpec) |
|
41 |
+ return SZ_ERROR_MEM; |
|
42 |
+ *blockIndex = folderIndex; |
|
43 |
+ IAlloc_Free(allocMain, *outBuffer); |
|
44 |
+ *outBuffer = 0; |
|
45 |
+ |
|
46 |
+ RINOK(LookInStream_SeekTo(inStream, startOffset)); |
|
47 |
+ |
|
48 |
+ if (res == SZ_OK) |
|
49 |
+ { |
|
50 |
+ *outBufferSize = unpackSize; |
|
51 |
+ if (unpackSize != 0) |
|
52 |
+ { |
|
53 |
+ *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); |
|
54 |
+ if (*outBuffer == 0) |
|
55 |
+ res = SZ_ERROR_MEM; |
|
56 |
+ } |
|
57 |
+ if (res == SZ_OK) |
|
58 |
+ { |
|
59 |
+ res = SzDecode(p->db.PackSizes + |
|
60 |
+ p->FolderStartPackStreamIndex[folderIndex], folder, |
|
61 |
+ inStream, startOffset, |
|
62 |
+ *outBuffer, unpackSize, allocTemp); |
|
63 |
+ if (res == SZ_OK) |
|
64 |
+ { |
|
65 |
+ if (folder->UnpackCRCDefined) |
|
66 |
+ { |
|
67 |
+ if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) |
|
68 |
+ res = SZ_ERROR_CRC; |
|
69 |
+ } |
|
70 |
+ } |
|
71 |
+ } |
|
72 |
+ } |
|
73 |
+ } |
|
74 |
+ if (res == SZ_OK) |
|
75 |
+ { |
|
76 |
+ UInt32 i; |
|
77 |
+ CSzFileItem *fileItem = p->db.Files + fileIndex; |
|
78 |
+ *offset = 0; |
|
79 |
+ for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) |
|
80 |
+ *offset += (UInt32)p->db.Files[i].Size; |
|
81 |
+ *outSizeProcessed = (size_t)fileItem->Size; |
|
82 |
+ if (*offset + *outSizeProcessed > *outBufferSize) |
|
83 |
+ return SZ_ERROR_FAIL; |
|
84 |
+ { |
|
85 |
+ if (fileItem->FileCRCDefined) |
|
86 |
+ { |
|
87 |
+ if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) |
|
88 |
+ res = SZ_ERROR_CRC; |
|
89 |
+ } |
|
90 |
+ } |
|
91 |
+ } |
|
92 |
+ return res; |
|
93 |
+} |
... | ... |
@@ -1,41 +1,41 @@ |
1 |
-/* 7zExtract.h -- Extracting from 7z archive |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_EXTRACT_H |
|
5 |
-#define __7Z_EXTRACT_H |
|
6 |
- |
|
7 |
-#include "7zIn.h" |
|
8 |
- |
|
9 |
-/* |
|
10 |
- SzExtract extracts file from archive |
|
11 |
- |
|
12 |
- *outBuffer must be 0 before first call for each new archive. |
|
13 |
- |
|
14 |
- Extracting cache: |
|
15 |
- If you need to decompress more than one file, you can send |
|
16 |
- these values from previous call: |
|
17 |
- *blockIndex, |
|
18 |
- *outBuffer, |
|
19 |
- *outBufferSize |
|
20 |
- You can consider "*outBuffer" as cache of solid block. If your archive is solid, |
|
21 |
- it will increase decompression speed. |
|
22 |
- |
|
23 |
- If you use external function, you can declare these 3 cache variables |
|
24 |
- (blockIndex, outBuffer, outBufferSize) as static in that external function. |
|
25 |
- |
|
26 |
- Free *outBuffer and set *outBuffer to 0, if you want to flush cache. |
|
27 |
-*/ |
|
28 |
- |
|
29 |
-SRes SzAr_Extract( |
|
30 |
- const CSzArEx *db, |
|
31 |
- ILookInStream *inStream, |
|
32 |
- UInt32 fileIndex, /* index of file */ |
|
33 |
- UInt32 *blockIndex, /* index of solid block */ |
|
34 |
- Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ |
|
35 |
- size_t *outBufferSize, /* buffer size for output buffer */ |
|
36 |
- size_t *offset, /* offset of stream for required file in *outBuffer */ |
|
37 |
- size_t *outSizeProcessed, /* size of file in *outBuffer */ |
|
38 |
- ISzAlloc *allocMain, |
|
39 |
- ISzAlloc *allocTemp); |
|
40 |
- |
|
41 |
-#endif |
|
1 |
+/* 7zExtract.h -- Extracting from 7z archive |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_EXTRACT_H |
|
5 |
+#define __7Z_EXTRACT_H |
|
6 |
+ |
|
7 |
+#include "7zIn.h" |
|
8 |
+ |
|
9 |
+/* |
|
10 |
+ SzExtract extracts file from archive |
|
11 |
+ |
|
12 |
+ *outBuffer must be 0 before first call for each new archive. |
|
13 |
+ |
|
14 |
+ Extracting cache: |
|
15 |
+ If you need to decompress more than one file, you can send |
|
16 |
+ these values from previous call: |
|
17 |
+ *blockIndex, |
|
18 |
+ *outBuffer, |
|
19 |
+ *outBufferSize |
|
20 |
+ You can consider "*outBuffer" as cache of solid block. If your archive is solid, |
|
21 |
+ it will increase decompression speed. |
|
22 |
+ |
|
23 |
+ If you use external function, you can declare these 3 cache variables |
|
24 |
+ (blockIndex, outBuffer, outBufferSize) as static in that external function. |
|
25 |
+ |
|
26 |
+ Free *outBuffer and set *outBuffer to 0, if you want to flush cache. |
|
27 |
+*/ |
|
28 |
+ |
|
29 |
+SRes SzAr_Extract( |
|
30 |
+ const CSzArEx *db, |
|
31 |
+ ILookInStream *inStream, |
|
32 |
+ UInt32 fileIndex, /* index of file */ |
|
33 |
+ UInt32 *blockIndex, /* index of solid block */ |
|
34 |
+ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ |
|
35 |
+ size_t *outBufferSize, /* buffer size for output buffer */ |
|
36 |
+ size_t *offset, /* offset of stream for required file in *outBuffer */ |
|
37 |
+ size_t *outSizeProcessed, /* size of file in *outBuffer */ |
|
38 |
+ ISzAlloc *allocMain, |
|
39 |
+ ISzAlloc *allocTemp); |
|
40 |
+ |
|
41 |
+#endif |
... | ... |
@@ -1,6 +1,6 @@ |
1 |
-/* 7zHeader.c -- 7z Headers |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "7zHeader.h" |
|
5 |
- |
|
6 |
-Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; |
|
1 |
+/* 7zHeader.c -- 7z Headers |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "7zHeader.h" |
|
5 |
+ |
|
6 |
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; |
... | ... |
@@ -1,57 +1,57 @@ |
1 |
-/* 7zHeader.h -- 7z Headers |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_HEADER_H |
|
5 |
-#define __7Z_HEADER_H |
|
6 |
- |
|
7 |
-#include "../../Types.h" |
|
8 |
- |
|
9 |
-#define k7zSignatureSize 6 |
|
10 |
-extern Byte k7zSignature[k7zSignatureSize]; |
|
11 |
- |
|
12 |
-#define k7zMajorVersion 0 |
|
13 |
- |
|
14 |
-#define k7zStartHeaderSize 0x20 |
|
15 |
- |
|
16 |
-enum EIdEnum |
|
17 |
-{ |
|
18 |
- k7zIdEnd, |
|
19 |
- |
|
20 |
- k7zIdHeader, |
|
21 |
- |
|
22 |
- k7zIdArchiveProperties, |
|
23 |
- |
|
24 |
- k7zIdAdditionalStreamsInfo, |
|
25 |
- k7zIdMainStreamsInfo, |
|
26 |
- k7zIdFilesInfo, |
|
27 |
- |
|
28 |
- k7zIdPackInfo, |
|
29 |
- k7zIdUnpackInfo, |
|
30 |
- k7zIdSubStreamsInfo, |
|
31 |
- |
|
32 |
- k7zIdSize, |
|
33 |
- k7zIdCRC, |
|
34 |
- |
|
35 |
- k7zIdFolder, |
|
36 |
- |
|
37 |
- k7zIdCodersUnpackSize, |
|
38 |
- k7zIdNumUnpackStream, |
|
39 |
- |
|
40 |
- k7zIdEmptyStream, |
|
41 |
- k7zIdEmptyFile, |
|
42 |
- k7zIdAnti, |
|
43 |
- |
|
44 |
- k7zIdName, |
|
45 |
- k7zIdCTime, |
|
46 |
- k7zIdATime, |
|
47 |
- k7zIdMTime, |
|
48 |
- k7zIdWinAttributes, |
|
49 |
- k7zIdComment, |
|
50 |
- |
|
51 |
- k7zIdEncodedHeader, |
|
52 |
- |
|
53 |
- k7zIdStartPos, |
|
54 |
- k7zIdDummy |
|
55 |
-}; |
|
56 |
- |
|
57 |
-#endif |
|
1 |
+/* 7zHeader.h -- 7z Headers |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_HEADER_H |
|
5 |
+#define __7Z_HEADER_H |
|
6 |
+ |
|
7 |
+#include "../../Types.h" |
|
8 |
+ |
|
9 |
+#define k7zSignatureSize 6 |
|
10 |
+extern Byte k7zSignature[k7zSignatureSize]; |
|
11 |
+ |
|
12 |
+#define k7zMajorVersion 0 |
|
13 |
+ |
|
14 |
+#define k7zStartHeaderSize 0x20 |
|
15 |
+ |
|
16 |
+enum EIdEnum |
|
17 |
+{ |
|
18 |
+ k7zIdEnd, |
|
19 |
+ |
|
20 |
+ k7zIdHeader, |
|
21 |
+ |
|
22 |
+ k7zIdArchiveProperties, |
|
23 |
+ |
|
24 |
+ k7zIdAdditionalStreamsInfo, |
|
25 |
+ k7zIdMainStreamsInfo, |
|
26 |
+ k7zIdFilesInfo, |
|
27 |
+ |
|
28 |
+ k7zIdPackInfo, |
|
29 |
+ k7zIdUnpackInfo, |
|
30 |
+ k7zIdSubStreamsInfo, |
|
31 |
+ |
|
32 |
+ k7zIdSize, |
|
33 |
+ k7zIdCRC, |
|
34 |
+ |
|
35 |
+ k7zIdFolder, |
|
36 |
+ |
|
37 |
+ k7zIdCodersUnpackSize, |
|
38 |
+ k7zIdNumUnpackStream, |
|
39 |
+ |
|
40 |
+ k7zIdEmptyStream, |
|
41 |
+ k7zIdEmptyFile, |
|
42 |
+ k7zIdAnti, |
|
43 |
+ |
|
44 |
+ k7zIdName, |
|
45 |
+ k7zIdCTime, |
|
46 |
+ k7zIdATime, |
|
47 |
+ k7zIdMTime, |
|
48 |
+ k7zIdWinAttributes, |
|
49 |
+ k7zIdComment, |
|
50 |
+ |
|
51 |
+ k7zIdEncodedHeader, |
|
52 |
+ |
|
53 |
+ k7zIdStartPos, |
|
54 |
+ k7zIdDummy |
|
55 |
+}; |
|
56 |
+ |
|
57 |
+#endif |
... | ... |
@@ -1,1204 +1,1204 @@ |
1 |
-/* 7zIn.c -- 7z Input functions |
|
2 |
-2008-12-31 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "../../7zCrc.h" |
|
5 |
-#include "../../CpuArch.h" |
|
6 |
- |
|
7 |
-#include "7zDecode.h" |
|
8 |
-#include "7zIn.h" |
|
9 |
- |
|
10 |
-#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } |
|
11 |
- |
|
12 |
-#define NUM_FOLDER_CODERS_MAX 32 |
|
13 |
-#define NUM_CODER_STREAMS_MAX 32 |
|
14 |
- |
|
15 |
-void SzArEx_Init(CSzArEx *p) |
|
16 |
-{ |
|
17 |
- SzAr_Init(&p->db); |
|
18 |
- p->FolderStartPackStreamIndex = 0; |
|
19 |
- p->PackStreamStartPositions = 0; |
|
20 |
- p->FolderStartFileIndex = 0; |
|
21 |
- p->FileIndexToFolderIndexMap = 0; |
|
22 |
-} |
|
23 |
- |
|
24 |
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) |
|
25 |
-{ |
|
26 |
- IAlloc_Free(alloc, p->FolderStartPackStreamIndex); |
|
27 |
- IAlloc_Free(alloc, p->PackStreamStartPositions); |
|
28 |
- IAlloc_Free(alloc, p->FolderStartFileIndex); |
|
29 |
- IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); |
|
30 |
- SzAr_Free(&p->db, alloc); |
|
31 |
- SzArEx_Init(p); |
|
32 |
-} |
|
33 |
- |
|
34 |
-/* |
|
35 |
-UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const |
|
36 |
-{ |
|
37 |
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; |
|
38 |
-} |
|
39 |
- |
|
40 |
-UInt64 GetFilePackSize(int fileIndex) const |
|
41 |
-{ |
|
42 |
- int folderIndex = FileIndexToFolderIndexMap[fileIndex]; |
|
43 |
- if (folderIndex >= 0) |
|
44 |
- { |
|
45 |
- const CSzFolder &folderInfo = Folders[folderIndex]; |
|
46 |
- if (FolderStartFileIndex[folderIndex] == fileIndex) |
|
47 |
- return GetFolderFullPackSize(folderIndex); |
|
48 |
- } |
|
49 |
- return 0; |
|
50 |
-} |
|
51 |
-*/ |
|
52 |
- |
|
53 |
-#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ |
|
54 |
- if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } |
|
55 |
- |
|
56 |
-static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) |
|
57 |
-{ |
|
58 |
- UInt32 startPos = 0; |
|
59 |
- UInt64 startPosSize = 0; |
|
60 |
- UInt32 i; |
|
61 |
- UInt32 folderIndex = 0; |
|
62 |
- UInt32 indexInFolder = 0; |
|
63 |
- MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); |
|
64 |
- for (i = 0; i < p->db.NumFolders; i++) |
|
65 |
- { |
|
66 |
- p->FolderStartPackStreamIndex[i] = startPos; |
|
67 |
- startPos += p->db.Folders[i].NumPackStreams; |
|
68 |
- } |
|
69 |
- |
|
70 |
- MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); |
|
71 |
- |
|
72 |
- for (i = 0; i < p->db.NumPackStreams; i++) |
|
73 |
- { |
|
74 |
- p->PackStreamStartPositions[i] = startPosSize; |
|
75 |
- startPosSize += p->db.PackSizes[i]; |
|
76 |
- } |
|
77 |
- |
|
78 |
- MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); |
|
79 |
- MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); |
|
80 |
- |
|
81 |
- for (i = 0; i < p->db.NumFiles; i++) |
|
82 |
- { |
|
83 |
- CSzFileItem *file = p->db.Files + i; |
|
84 |
- int emptyStream = !file->HasStream; |
|
85 |
- if (emptyStream && indexInFolder == 0) |
|
86 |
- { |
|
87 |
- p->FileIndexToFolderIndexMap[i] = (UInt32)-1; |
|
88 |
- continue; |
|
89 |
- } |
|
90 |
- if (indexInFolder == 0) |
|
91 |
- { |
|
92 |
- /* |
|
93 |
- v3.13 incorrectly worked with empty folders |
|
94 |
- v4.07: Loop for skipping empty folders |
|
95 |
- */ |
|
96 |
- for (;;) |
|
97 |
- { |
|
98 |
- if (folderIndex >= p->db.NumFolders) |
|
99 |
- return SZ_ERROR_ARCHIVE; |
|
100 |
- p->FolderStartFileIndex[folderIndex] = i; |
|
101 |
- if (p->db.Folders[folderIndex].NumUnpackStreams != 0) |
|
102 |
- break; |
|
103 |
- folderIndex++; |
|
104 |
- } |
|
105 |
- } |
|
106 |
- p->FileIndexToFolderIndexMap[i] = folderIndex; |
|
107 |
- if (emptyStream) |
|
108 |
- continue; |
|
109 |
- indexInFolder++; |
|
110 |
- if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) |
|
111 |
- { |
|
112 |
- folderIndex++; |
|
113 |
- indexInFolder = 0; |
|
114 |
- } |
|
115 |
- } |
|
116 |
- return SZ_OK; |
|
117 |
-} |
|
118 |
- |
|
119 |
- |
|
120 |
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) |
|
121 |
-{ |
|
122 |
- return p->dataPos + |
|
123 |
- p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; |
|
124 |
-} |
|
125 |
- |
|
126 |
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) |
|
127 |
-{ |
|
128 |
- UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; |
|
129 |
- CSzFolder *folder = p->db.Folders + folderIndex; |
|
130 |
- UInt64 size = 0; |
|
131 |
- UInt32 i; |
|
132 |
- for (i = 0; i < folder->NumPackStreams; i++) |
|
133 |
- { |
|
134 |
- UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; |
|
135 |
- if (t < size) /* check it */ |
|
136 |
- return SZ_ERROR_FAIL; |
|
137 |
- size = t; |
|
138 |
- } |
|
139 |
- *resSize = size; |
|
140 |
- return SZ_OK; |
|
141 |
-} |
|
142 |
- |
|
143 |
- |
|
144 |
-/* |
|
145 |
-SRes SzReadTime(const CObjectVector<CBuf> &dataVector, |
|
146 |
- CObjectVector<CSzFileItem> &files, UInt64 type) |
|
147 |
-{ |
|
148 |
- CBoolVector boolVector; |
|
149 |
- RINOK(ReadBoolVector2(files.Size(), boolVector)) |
|
150 |
- |
|
151 |
- CStreamSwitch streamSwitch; |
|
152 |
- RINOK(streamSwitch.Set(this, &dataVector)); |
|
153 |
- |
|
154 |
- for (int i = 0; i < files.Size(); i++) |
|
155 |
- { |
|
156 |
- CSzFileItem &file = files[i]; |
|
157 |
- CArchiveFileTime fileTime; |
|
158 |
- bool defined = boolVector[i]; |
|
159 |
- if (defined) |
|
160 |
- { |
|
161 |
- UInt32 low, high; |
|
162 |
- RINOK(SzReadUInt32(low)); |
|
163 |
- RINOK(SzReadUInt32(high)); |
|
164 |
- fileTime.dwLowDateTime = low; |
|
165 |
- fileTime.dwHighDateTime = high; |
|
166 |
- } |
|
167 |
- switch(type) |
|
168 |
- { |
|
169 |
- case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; |
|
170 |
- case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; |
|
171 |
- case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; |
|
172 |
- } |
|
173 |
- } |
|
174 |
- return SZ_OK; |
|
175 |
-} |
|
176 |
-*/ |
|
177 |
- |
|
178 |
-static int TestSignatureCandidate(Byte *testBytes) |
|
179 |
-{ |
|
180 |
- size_t i; |
|
181 |
- for (i = 0; i < k7zSignatureSize; i++) |
|
182 |
- if (testBytes[i] != k7zSignature[i]) |
|
183 |
- return 0; |
|
184 |
- return 1; |
|
185 |
-} |
|
186 |
- |
|
187 |
-typedef struct _CSzState |
|
188 |
-{ |
|
189 |
- Byte *Data; |
|
190 |
- size_t Size; |
|
191 |
-}CSzData; |
|
192 |
- |
|
193 |
-static SRes SzReadByte(CSzData *sd, Byte *b) |
|
194 |
-{ |
|
195 |
- if (sd->Size == 0) |
|
196 |
- return SZ_ERROR_ARCHIVE; |
|
197 |
- sd->Size--; |
|
198 |
- *b = *sd->Data++; |
|
199 |
- return SZ_OK; |
|
200 |
-} |
|
201 |
- |
|
202 |
-static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) |
|
203 |
-{ |
|
204 |
- size_t i; |
|
205 |
- for (i = 0; i < size; i++) |
|
206 |
- { |
|
207 |
- RINOK(SzReadByte(sd, data + i)); |
|
208 |
- } |
|
209 |
- return SZ_OK; |
|
210 |
-} |
|
211 |
- |
|
212 |
-static SRes SzReadUInt32(CSzData *sd, UInt32 *value) |
|
213 |
-{ |
|
214 |
- int i; |
|
215 |
- *value = 0; |
|
216 |
- for (i = 0; i < 4; i++) |
|
217 |
- { |
|
218 |
- Byte b; |
|
219 |
- RINOK(SzReadByte(sd, &b)); |
|
220 |
- *value |= ((UInt32)(b) << (8 * i)); |
|
221 |
- } |
|
222 |
- return SZ_OK; |
|
223 |
-} |
|
224 |
- |
|
225 |
-static SRes SzReadNumber(CSzData *sd, UInt64 *value) |
|
226 |
-{ |
|
227 |
- Byte firstByte; |
|
228 |
- Byte mask = 0x80; |
|
229 |
- int i; |
|
230 |
- RINOK(SzReadByte(sd, &firstByte)); |
|
231 |
- *value = 0; |
|
232 |
- for (i = 0; i < 8; i++) |
|
233 |
- { |
|
234 |
- Byte b; |
|
235 |
- if ((firstByte & mask) == 0) |
|
236 |
- { |
|
237 |
- UInt64 highPart = firstByte & (mask - 1); |
|
238 |
- *value += (highPart << (8 * i)); |
|
239 |
- return SZ_OK; |
|
240 |
- } |
|
241 |
- RINOK(SzReadByte(sd, &b)); |
|
242 |
- *value |= ((UInt64)b << (8 * i)); |
|
243 |
- mask >>= 1; |
|
244 |
- } |
|
245 |
- return SZ_OK; |
|
246 |
-} |
|
247 |
- |
|
248 |
-static SRes SzReadNumber32(CSzData *sd, UInt32 *value) |
|
249 |
-{ |
|
250 |
- UInt64 value64; |
|
251 |
- RINOK(SzReadNumber(sd, &value64)); |
|
252 |
- if (value64 >= 0x80000000) |
|
253 |
- return SZ_ERROR_UNSUPPORTED; |
|
254 |
- if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) |
|
255 |
- return SZ_ERROR_UNSUPPORTED; |
|
256 |
- *value = (UInt32)value64; |
|
257 |
- return SZ_OK; |
|
258 |
-} |
|
259 |
- |
|
260 |
-static SRes SzReadID(CSzData *sd, UInt64 *value) |
|
261 |
-{ |
|
262 |
- return SzReadNumber(sd, value); |
|
263 |
-} |
|
264 |
- |
|
265 |
-static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) |
|
266 |
-{ |
|
267 |
- if (size > sd->Size) |
|
268 |
- return SZ_ERROR_ARCHIVE; |
|
269 |
- sd->Size -= (size_t)size; |
|
270 |
- sd->Data += (size_t)size; |
|
271 |
- return SZ_OK; |
|
272 |
-} |
|
273 |
- |
|
274 |
-static SRes SzSkeepData(CSzData *sd) |
|
275 |
-{ |
|
276 |
- UInt64 size; |
|
277 |
- RINOK(SzReadNumber(sd, &size)); |
|
278 |
- return SzSkeepDataSize(sd, size); |
|
279 |
-} |
|
280 |
- |
|
281 |
-static SRes SzReadArchiveProperties(CSzData *sd) |
|
282 |
-{ |
|
283 |
- for (;;) |
|
284 |
- { |
|
285 |
- UInt64 type; |
|
286 |
- RINOK(SzReadID(sd, &type)); |
|
287 |
- if (type == k7zIdEnd) |
|
288 |
- break; |
|
289 |
- SzSkeepData(sd); |
|
290 |
- } |
|
291 |
- return SZ_OK; |
|
292 |
-} |
|
293 |
- |
|
294 |
-static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) |
|
295 |
-{ |
|
296 |
- for (;;) |
|
297 |
- { |
|
298 |
- UInt64 type; |
|
299 |
- RINOK(SzReadID(sd, &type)); |
|
300 |
- if (type == attribute) |
|
301 |
- return SZ_OK; |
|
302 |
- if (type == k7zIdEnd) |
|
303 |
- return SZ_ERROR_ARCHIVE; |
|
304 |
- RINOK(SzSkeepData(sd)); |
|
305 |
- } |
|
306 |
-} |
|
307 |
- |
|
308 |
-static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
309 |
-{ |
|
310 |
- Byte b = 0; |
|
311 |
- Byte mask = 0; |
|
312 |
- size_t i; |
|
313 |
- MY_ALLOC(Byte, *v, numItems, alloc); |
|
314 |
- for (i = 0; i < numItems; i++) |
|
315 |
- { |
|
316 |
- if (mask == 0) |
|
317 |
- { |
|
318 |
- RINOK(SzReadByte(sd, &b)); |
|
319 |
- mask = 0x80; |
|
320 |
- } |
|
321 |
- (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); |
|
322 |
- mask >>= 1; |
|
323 |
- } |
|
324 |
- return SZ_OK; |
|
325 |
-} |
|
326 |
- |
|
327 |
-static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
328 |
-{ |
|
329 |
- Byte allAreDefined; |
|
330 |
- size_t i; |
|
331 |
- RINOK(SzReadByte(sd, &allAreDefined)); |
|
332 |
- if (allAreDefined == 0) |
|
333 |
- return SzReadBoolVector(sd, numItems, v, alloc); |
|
334 |
- MY_ALLOC(Byte, *v, numItems, alloc); |
|
335 |
- for (i = 0; i < numItems; i++) |
|
336 |
- (*v)[i] = 1; |
|
337 |
- return SZ_OK; |
|
338 |
-} |
|
339 |
- |
|
340 |
-static SRes SzReadHashDigests( |
|
341 |
- CSzData *sd, |
|
342 |
- size_t numItems, |
|
343 |
- Byte **digestsDefined, |
|
344 |
- UInt32 **digests, |
|
345 |
- ISzAlloc *alloc) |
|
346 |
-{ |
|
347 |
- size_t i; |
|
348 |
- RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); |
|
349 |
- MY_ALLOC(UInt32, *digests, numItems, alloc); |
|
350 |
- for (i = 0; i < numItems; i++) |
|
351 |
- if ((*digestsDefined)[i]) |
|
352 |
- { |
|
353 |
- RINOK(SzReadUInt32(sd, (*digests) + i)); |
|
354 |
- } |
|
355 |
- return SZ_OK; |
|
356 |
-} |
|
357 |
- |
|
358 |
-static SRes SzReadPackInfo( |
|
359 |
- CSzData *sd, |
|
360 |
- UInt64 *dataOffset, |
|
361 |
- UInt32 *numPackStreams, |
|
362 |
- UInt64 **packSizes, |
|
363 |
- Byte **packCRCsDefined, |
|
364 |
- UInt32 **packCRCs, |
|
365 |
- ISzAlloc *alloc) |
|
366 |
-{ |
|
367 |
- UInt32 i; |
|
368 |
- RINOK(SzReadNumber(sd, dataOffset)); |
|
369 |
- RINOK(SzReadNumber32(sd, numPackStreams)); |
|
370 |
- |
|
371 |
- RINOK(SzWaitAttribute(sd, k7zIdSize)); |
|
372 |
- |
|
373 |
- MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); |
|
374 |
- |
|
375 |
- for (i = 0; i < *numPackStreams; i++) |
|
376 |
- { |
|
377 |
- RINOK(SzReadNumber(sd, (*packSizes) + i)); |
|
378 |
- } |
|
379 |
- |
|
380 |
- for (;;) |
|
381 |
- { |
|
382 |
- UInt64 type; |
|
383 |
- RINOK(SzReadID(sd, &type)); |
|
384 |
- if (type == k7zIdEnd) |
|
385 |
- break; |
|
386 |
- if (type == k7zIdCRC) |
|
387 |
- { |
|
388 |
- RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); |
|
389 |
- continue; |
|
390 |
- } |
|
391 |
- RINOK(SzSkeepData(sd)); |
|
392 |
- } |
|
393 |
- if (*packCRCsDefined == 0) |
|
394 |
- { |
|
395 |
- MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); |
|
396 |
- MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); |
|
397 |
- for (i = 0; i < *numPackStreams; i++) |
|
398 |
- { |
|
399 |
- (*packCRCsDefined)[i] = 0; |
|
400 |
- (*packCRCs)[i] = 0; |
|
401 |
- } |
|
402 |
- } |
|
403 |
- return SZ_OK; |
|
404 |
-} |
|
405 |
- |
|
406 |
-static SRes SzReadSwitch(CSzData *sd) |
|
407 |
-{ |
|
408 |
- Byte external; |
|
409 |
- RINOK(SzReadByte(sd, &external)); |
|
410 |
- return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; |
|
411 |
-} |
|
412 |
- |
|
413 |
-static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) |
|
414 |
-{ |
|
415 |
- UInt32 numCoders, numBindPairs, numPackStreams, i; |
|
416 |
- UInt32 numInStreams = 0, numOutStreams = 0; |
|
417 |
- |
|
418 |
- RINOK(SzReadNumber32(sd, &numCoders)); |
|
419 |
- if (numCoders > NUM_FOLDER_CODERS_MAX) |
|
420 |
- return SZ_ERROR_UNSUPPORTED; |
|
421 |
- folder->NumCoders = numCoders; |
|
422 |
- |
|
423 |
- MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); |
|
424 |
- |
|
425 |
- for (i = 0; i < numCoders; i++) |
|
426 |
- SzCoderInfo_Init(folder->Coders + i); |
|
427 |
- |
|
428 |
- for (i = 0; i < numCoders; i++) |
|
429 |
- { |
|
430 |
- Byte mainByte; |
|
431 |
- CSzCoderInfo *coder = folder->Coders + i; |
|
432 |
- { |
|
433 |
- unsigned idSize, j; |
|
434 |
- Byte longID[15]; |
|
435 |
- RINOK(SzReadByte(sd, &mainByte)); |
|
436 |
- idSize = (unsigned)(mainByte & 0xF); |
|
437 |
- RINOK(SzReadBytes(sd, longID, idSize)); |
|
438 |
- if (idSize > sizeof(coder->MethodID)) |
|
439 |
- return SZ_ERROR_UNSUPPORTED; |
|
440 |
- coder->MethodID = 0; |
|
441 |
- for (j = 0; j < idSize; j++) |
|
442 |
- coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); |
|
443 |
- |
|
444 |
- if ((mainByte & 0x10) != 0) |
|
445 |
- { |
|
446 |
- RINOK(SzReadNumber32(sd, &coder->NumInStreams)); |
|
447 |
- RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); |
|
448 |
- if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || |
|
449 |
- coder->NumOutStreams > NUM_CODER_STREAMS_MAX) |
|
450 |
- return SZ_ERROR_UNSUPPORTED; |
|
451 |
- } |
|
452 |
- else |
|
453 |
- { |
|
454 |
- coder->NumInStreams = 1; |
|
455 |
- coder->NumOutStreams = 1; |
|
456 |
- } |
|
457 |
- if ((mainByte & 0x20) != 0) |
|
458 |
- { |
|
459 |
- UInt64 propertiesSize = 0; |
|
460 |
- RINOK(SzReadNumber(sd, &propertiesSize)); |
|
461 |
- if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) |
|
462 |
- return SZ_ERROR_MEM; |
|
463 |
- RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); |
|
464 |
- } |
|
465 |
- } |
|
466 |
- while ((mainByte & 0x80) != 0) |
|
467 |
- { |
|
468 |
- RINOK(SzReadByte(sd, &mainByte)); |
|
469 |
- RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); |
|
470 |
- if ((mainByte & 0x10) != 0) |
|
471 |
- { |
|
472 |
- UInt32 n; |
|
473 |
- RINOK(SzReadNumber32(sd, &n)); |
|
474 |
- RINOK(SzReadNumber32(sd, &n)); |
|
475 |
- } |
|
476 |
- if ((mainByte & 0x20) != 0) |
|
477 |
- { |
|
478 |
- UInt64 propertiesSize = 0; |
|
479 |
- RINOK(SzReadNumber(sd, &propertiesSize)); |
|
480 |
- RINOK(SzSkeepDataSize(sd, propertiesSize)); |
|
481 |
- } |
|
482 |
- } |
|
483 |
- numInStreams += coder->NumInStreams; |
|
484 |
- numOutStreams += coder->NumOutStreams; |
|
485 |
- } |
|
486 |
- |
|
487 |
- if (numOutStreams == 0) |
|
488 |
- return SZ_ERROR_UNSUPPORTED; |
|
489 |
- |
|
490 |
- folder->NumBindPairs = numBindPairs = numOutStreams - 1; |
|
491 |
- MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); |
|
492 |
- |
|
493 |
- for (i = 0; i < numBindPairs; i++) |
|
494 |
- { |
|
495 |
- CBindPair *bp = folder->BindPairs + i; |
|
496 |
- RINOK(SzReadNumber32(sd, &bp->InIndex)); |
|
497 |
- RINOK(SzReadNumber32(sd, &bp->OutIndex)); |
|
498 |
- } |
|
499 |
- |
|
500 |
- if (numInStreams < numBindPairs) |
|
501 |
- return SZ_ERROR_UNSUPPORTED; |
|
502 |
- |
|
503 |
- folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; |
|
504 |
- MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); |
|
505 |
- |
|
506 |
- if (numPackStreams == 1) |
|
507 |
- { |
|
508 |
- for (i = 0; i < numInStreams ; i++) |
|
509 |
- if (SzFolder_FindBindPairForInStream(folder, i) < 0) |
|
510 |
- break; |
|
511 |
- if (i == numInStreams) |
|
512 |
- return SZ_ERROR_UNSUPPORTED; |
|
513 |
- folder->PackStreams[0] = i; |
|
514 |
- } |
|
515 |
- else |
|
516 |
- for (i = 0; i < numPackStreams; i++) |
|
517 |
- { |
|
518 |
- RINOK(SzReadNumber32(sd, folder->PackStreams + i)); |
|
519 |
- } |
|
520 |
- return SZ_OK; |
|
521 |
-} |
|
522 |
- |
|
523 |
-static SRes SzReadUnpackInfo( |
|
524 |
- CSzData *sd, |
|
525 |
- UInt32 *numFolders, |
|
526 |
- CSzFolder **folders, /* for alloc */ |
|
527 |
- ISzAlloc *alloc, |
|
528 |
- ISzAlloc *allocTemp) |
|
529 |
-{ |
|
530 |
- UInt32 i; |
|
531 |
- RINOK(SzWaitAttribute(sd, k7zIdFolder)); |
|
532 |
- RINOK(SzReadNumber32(sd, numFolders)); |
|
533 |
- { |
|
534 |
- RINOK(SzReadSwitch(sd)); |
|
535 |
- |
|
536 |
- MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); |
|
537 |
- |
|
538 |
- for (i = 0; i < *numFolders; i++) |
|
539 |
- SzFolder_Init((*folders) + i); |
|
540 |
- |
|
541 |
- for (i = 0; i < *numFolders; i++) |
|
542 |
- { |
|
543 |
- RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); |
|
544 |
- } |
|
545 |
- } |
|
546 |
- |
|
547 |
- RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); |
|
548 |
- |
|
549 |
- for (i = 0; i < *numFolders; i++) |
|
550 |
- { |
|
551 |
- UInt32 j; |
|
552 |
- CSzFolder *folder = (*folders) + i; |
|
553 |
- UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); |
|
554 |
- |
|
555 |
- MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); |
|
556 |
- |
|
557 |
- for (j = 0; j < numOutStreams; j++) |
|
558 |
- { |
|
559 |
- RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); |
|
560 |
- } |
|
561 |
- } |
|
562 |
- |
|
563 |
- for (;;) |
|
564 |
- { |
|
565 |
- UInt64 type; |
|
566 |
- RINOK(SzReadID(sd, &type)); |
|
567 |
- if (type == k7zIdEnd) |
|
568 |
- return SZ_OK; |
|
569 |
- if (type == k7zIdCRC) |
|
570 |
- { |
|
571 |
- SRes res; |
|
572 |
- Byte *crcsDefined = 0; |
|
573 |
- UInt32 *crcs = 0; |
|
574 |
- res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); |
|
575 |
- if (res == SZ_OK) |
|
576 |
- { |
|
577 |
- for (i = 0; i < *numFolders; i++) |
|
578 |
- { |
|
579 |
- CSzFolder *folder = (*folders) + i; |
|
580 |
- folder->UnpackCRCDefined = crcsDefined[i]; |
|
581 |
- folder->UnpackCRC = crcs[i]; |
|
582 |
- } |
|
583 |
- } |
|
584 |
- IAlloc_Free(allocTemp, crcs); |
|
585 |
- IAlloc_Free(allocTemp, crcsDefined); |
|
586 |
- RINOK(res); |
|
587 |
- continue; |
|
588 |
- } |
|
589 |
- RINOK(SzSkeepData(sd)); |
|
590 |
- } |
|
591 |
-} |
|
592 |
- |
|
593 |
-static SRes SzReadSubStreamsInfo( |
|
594 |
- CSzData *sd, |
|
595 |
- UInt32 numFolders, |
|
596 |
- CSzFolder *folders, |
|
597 |
- UInt32 *numUnpackStreams, |
|
598 |
- UInt64 **unpackSizes, |
|
599 |
- Byte **digestsDefined, |
|
600 |
- UInt32 **digests, |
|
601 |
- ISzAlloc *allocTemp) |
|
602 |
-{ |
|
603 |
- UInt64 type = 0; |
|
604 |
- UInt32 i; |
|
605 |
- UInt32 si = 0; |
|
606 |
- UInt32 numDigests = 0; |
|
607 |
- |
|
608 |
- for (i = 0; i < numFolders; i++) |
|
609 |
- folders[i].NumUnpackStreams = 1; |
|
610 |
- *numUnpackStreams = numFolders; |
|
611 |
- |
|
612 |
- for (;;) |
|
613 |
- { |
|
614 |
- RINOK(SzReadID(sd, &type)); |
|
615 |
- if (type == k7zIdNumUnpackStream) |
|
616 |
- { |
|
617 |
- *numUnpackStreams = 0; |
|
618 |
- for (i = 0; i < numFolders; i++) |
|
619 |
- { |
|
620 |
- UInt32 numStreams; |
|
621 |
- RINOK(SzReadNumber32(sd, &numStreams)); |
|
622 |
- folders[i].NumUnpackStreams = numStreams; |
|
623 |
- *numUnpackStreams += numStreams; |
|
624 |
- } |
|
625 |
- continue; |
|
626 |
- } |
|
627 |
- if (type == k7zIdCRC || type == k7zIdSize) |
|
628 |
- break; |
|
629 |
- if (type == k7zIdEnd) |
|
630 |
- break; |
|
631 |
- RINOK(SzSkeepData(sd)); |
|
632 |
- } |
|
633 |
- |
|
634 |
- if (*numUnpackStreams == 0) |
|
635 |
- { |
|
636 |
- *unpackSizes = 0; |
|
637 |
- *digestsDefined = 0; |
|
638 |
- *digests = 0; |
|
639 |
- } |
|
640 |
- else |
|
641 |
- { |
|
642 |
- *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); |
|
643 |
- RINOM(*unpackSizes); |
|
644 |
- *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); |
|
645 |
- RINOM(*digestsDefined); |
|
646 |
- *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); |
|
647 |
- RINOM(*digests); |
|
648 |
- } |
|
649 |
- |
|
650 |
- for (i = 0; i < numFolders; i++) |
|
651 |
- { |
|
652 |
- /* |
|
653 |
- v3.13 incorrectly worked with empty folders |
|
654 |
- v4.07: we check that folder is empty |
|
655 |
- */ |
|
656 |
- UInt64 sum = 0; |
|
657 |
- UInt32 j; |
|
658 |
- UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
659 |
- if (numSubstreams == 0) |
|
660 |
- continue; |
|
661 |
- if (type == k7zIdSize) |
|
662 |
- for (j = 1; j < numSubstreams; j++) |
|
663 |
- { |
|
664 |
- UInt64 size; |
|
665 |
- RINOK(SzReadNumber(sd, &size)); |
|
666 |
- (*unpackSizes)[si++] = size; |
|
667 |
- sum += size; |
|
668 |
- } |
|
669 |
- (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; |
|
670 |
- } |
|
671 |
- if (type == k7zIdSize) |
|
672 |
- { |
|
673 |
- RINOK(SzReadID(sd, &type)); |
|
674 |
- } |
|
675 |
- |
|
676 |
- for (i = 0; i < *numUnpackStreams; i++) |
|
677 |
- { |
|
678 |
- (*digestsDefined)[i] = 0; |
|
679 |
- (*digests)[i] = 0; |
|
680 |
- } |
|
681 |
- |
|
682 |
- |
|
683 |
- for (i = 0; i < numFolders; i++) |
|
684 |
- { |
|
685 |
- UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
686 |
- if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) |
|
687 |
- numDigests += numSubstreams; |
|
688 |
- } |
|
689 |
- |
|
690 |
- |
|
691 |
- si = 0; |
|
692 |
- for (;;) |
|
693 |
- { |
|
694 |
- if (type == k7zIdCRC) |
|
695 |
- { |
|
696 |
- int digestIndex = 0; |
|
697 |
- Byte *digestsDefined2 = 0; |
|
698 |
- UInt32 *digests2 = 0; |
|
699 |
- SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); |
|
700 |
- if (res == SZ_OK) |
|
701 |
- { |
|
702 |
- for (i = 0; i < numFolders; i++) |
|
703 |
- { |
|
704 |
- CSzFolder *folder = folders + i; |
|
705 |
- UInt32 numSubstreams = folder->NumUnpackStreams; |
|
706 |
- if (numSubstreams == 1 && folder->UnpackCRCDefined) |
|
707 |
- { |
|
708 |
- (*digestsDefined)[si] = 1; |
|
709 |
- (*digests)[si] = folder->UnpackCRC; |
|
710 |
- si++; |
|
711 |
- } |
|
712 |
- else |
|
713 |
- { |
|
714 |
- UInt32 j; |
|
715 |
- for (j = 0; j < numSubstreams; j++, digestIndex++) |
|
716 |
- { |
|
717 |
- (*digestsDefined)[si] = digestsDefined2[digestIndex]; |
|
718 |
- (*digests)[si] = digests2[digestIndex]; |
|
719 |
- si++; |
|
720 |
- } |
|
721 |
- } |
|
722 |
- } |
|
723 |
- } |
|
724 |
- IAlloc_Free(allocTemp, digestsDefined2); |
|
725 |
- IAlloc_Free(allocTemp, digests2); |
|
726 |
- RINOK(res); |
|
727 |
- } |
|
728 |
- else if (type == k7zIdEnd) |
|
729 |
- return SZ_OK; |
|
730 |
- else |
|
731 |
- { |
|
732 |
- RINOK(SzSkeepData(sd)); |
|
733 |
- } |
|
734 |
- RINOK(SzReadID(sd, &type)); |
|
735 |
- } |
|
736 |
-} |
|
737 |
- |
|
738 |
- |
|
739 |
-static SRes SzReadStreamsInfo( |
|
740 |
- CSzData *sd, |
|
741 |
- UInt64 *dataOffset, |
|
742 |
- CSzAr *p, |
|
743 |
- UInt32 *numUnpackStreams, |
|
744 |
- UInt64 **unpackSizes, /* allocTemp */ |
|
745 |
- Byte **digestsDefined, /* allocTemp */ |
|
746 |
- UInt32 **digests, /* allocTemp */ |
|
747 |
- ISzAlloc *alloc, |
|
748 |
- ISzAlloc *allocTemp) |
|
749 |
-{ |
|
750 |
- for (;;) |
|
751 |
- { |
|
752 |
- UInt64 type; |
|
753 |
- RINOK(SzReadID(sd, &type)); |
|
754 |
- if ((UInt64)(int)type != type) |
|
755 |
- return SZ_ERROR_UNSUPPORTED; |
|
756 |
- switch((int)type) |
|
757 |
- { |
|
758 |
- case k7zIdEnd: |
|
759 |
- return SZ_OK; |
|
760 |
- case k7zIdPackInfo: |
|
761 |
- { |
|
762 |
- RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, |
|
763 |
- &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); |
|
764 |
- break; |
|
765 |
- } |
|
766 |
- case k7zIdUnpackInfo: |
|
767 |
- { |
|
768 |
- RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); |
|
769 |
- break; |
|
770 |
- } |
|
771 |
- case k7zIdSubStreamsInfo: |
|
772 |
- { |
|
773 |
- RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, |
|
774 |
- numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); |
|
775 |
- break; |
|
776 |
- } |
|
777 |
- default: |
|
778 |
- return SZ_ERROR_UNSUPPORTED; |
|
779 |
- } |
|
780 |
- } |
|
781 |
-} |
|
782 |
- |
|
783 |
-Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; |
|
784 |
- |
|
785 |
-static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) |
|
786 |
-{ |
|
787 |
- UInt32 i; |
|
788 |
- for (i = 0; i < numFiles; i++) |
|
789 |
- { |
|
790 |
- UInt32 len = 0; |
|
791 |
- UInt32 pos = 0; |
|
792 |
- CSzFileItem *file = files + i; |
|
793 |
- while (pos + 2 <= sd->Size) |
|
794 |
- { |
|
795 |
- int numAdds; |
|
796 |
- UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); |
|
797 |
- pos += 2; |
|
798 |
- len++; |
|
799 |
- if (value == 0) |
|
800 |
- break; |
|
801 |
- if (value < 0x80) |
|
802 |
- continue; |
|
803 |
- if (value >= 0xD800 && value < 0xE000) |
|
804 |
- { |
|
805 |
- UInt32 c2; |
|
806 |
- if (value >= 0xDC00) |
|
807 |
- return SZ_ERROR_ARCHIVE; |
|
808 |
- if (pos + 2 > sd->Size) |
|
809 |
- return SZ_ERROR_ARCHIVE; |
|
810 |
- c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); |
|
811 |
- pos += 2; |
|
812 |
- if (c2 < 0xDC00 || c2 >= 0xE000) |
|
813 |
- return SZ_ERROR_ARCHIVE; |
|
814 |
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00); |
|
815 |
- } |
|
816 |
- for (numAdds = 1; numAdds < 5; numAdds++) |
|
817 |
- if (value < (((UInt32)1) << (numAdds * 5 + 6))) |
|
818 |
- break; |
|
819 |
- len += numAdds; |
|
820 |
- } |
|
821 |
- |
|
822 |
- MY_ALLOC(char, file->Name, (size_t)len, alloc); |
|
823 |
- |
|
824 |
- len = 0; |
|
825 |
- while (2 <= sd->Size) |
|
826 |
- { |
|
827 |
- int numAdds; |
|
828 |
- UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); |
|
829 |
- SzSkeepDataSize(sd, 2); |
|
830 |
- if (value < 0x80) |
|
831 |
- { |
|
832 |
- file->Name[len++] = (char)value; |
|
833 |
- if (value == 0) |
|
834 |
- break; |
|
835 |
- continue; |
|
836 |
- } |
|
837 |
- if (value >= 0xD800 && value < 0xE000) |
|
838 |
- { |
|
839 |
- UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); |
|
840 |
- SzSkeepDataSize(sd, 2); |
|
841 |
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00); |
|
842 |
- } |
|
843 |
- for (numAdds = 1; numAdds < 5; numAdds++) |
|
844 |
- if (value < (((UInt32)1) << (numAdds * 5 + 6))) |
|
845 |
- break; |
|
846 |
- file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); |
|
847 |
- do |
|
848 |
- { |
|
849 |
- numAdds--; |
|
850 |
- file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); |
|
851 |
- } |
|
852 |
- while (numAdds > 0); |
|
853 |
- |
|
854 |
- len += numAdds; |
|
855 |
- } |
|
856 |
- } |
|
857 |
- return SZ_OK; |
|
858 |
-} |
|
859 |
- |
|
860 |
-static SRes SzReadHeader2( |
|
861 |
- CSzArEx *p, /* allocMain */ |
|
862 |
- CSzData *sd, |
|
863 |
- UInt64 **unpackSizes, /* allocTemp */ |
|
864 |
- Byte **digestsDefined, /* allocTemp */ |
|
865 |
- UInt32 **digests, /* allocTemp */ |
|
866 |
- Byte **emptyStreamVector, /* allocTemp */ |
|
867 |
- Byte **emptyFileVector, /* allocTemp */ |
|
868 |
- Byte **lwtVector, /* allocTemp */ |
|
869 |
- ISzAlloc *allocMain, |
|
870 |
- ISzAlloc *allocTemp) |
|
871 |
-{ |
|
872 |
- UInt64 type; |
|
873 |
- UInt32 numUnpackStreams = 0; |
|
874 |
- UInt32 numFiles = 0; |
|
875 |
- CSzFileItem *files = 0; |
|
876 |
- UInt32 numEmptyStreams = 0; |
|
877 |
- UInt32 i; |
|
878 |
- |
|
879 |
- RINOK(SzReadID(sd, &type)); |
|
880 |
- |
|
881 |
- if (type == k7zIdArchiveProperties) |
|
882 |
- { |
|
883 |
- RINOK(SzReadArchiveProperties(sd)); |
|
884 |
- RINOK(SzReadID(sd, &type)); |
|
885 |
- } |
|
886 |
- |
|
887 |
- |
|
888 |
- if (type == k7zIdMainStreamsInfo) |
|
889 |
- { |
|
890 |
- RINOK(SzReadStreamsInfo(sd, |
|
891 |
- &p->dataPos, |
|
892 |
- &p->db, |
|
893 |
- &numUnpackStreams, |
|
894 |
- unpackSizes, |
|
895 |
- digestsDefined, |
|
896 |
- digests, allocMain, allocTemp)); |
|
897 |
- p->dataPos += p->startPosAfterHeader; |
|
898 |
- RINOK(SzReadID(sd, &type)); |
|
899 |
- } |
|
900 |
- |
|
901 |
- if (type == k7zIdEnd) |
|
902 |
- return SZ_OK; |
|
903 |
- if (type != k7zIdFilesInfo) |
|
904 |
- return SZ_ERROR_ARCHIVE; |
|
905 |
- |
|
906 |
- RINOK(SzReadNumber32(sd, &numFiles)); |
|
907 |
- p->db.NumFiles = numFiles; |
|
908 |
- |
|
909 |
- MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); |
|
910 |
- |
|
911 |
- p->db.Files = files; |
|
912 |
- for (i = 0; i < numFiles; i++) |
|
913 |
- SzFile_Init(files + i); |
|
914 |
- |
|
915 |
- for (;;) |
|
916 |
- { |
|
917 |
- UInt64 type; |
|
918 |
- UInt64 size; |
|
919 |
- RINOK(SzReadID(sd, &type)); |
|
920 |
- if (type == k7zIdEnd) |
|
921 |
- break; |
|
922 |
- RINOK(SzReadNumber(sd, &size)); |
|
923 |
- |
|
924 |
- if ((UInt64)(int)type != type) |
|
925 |
- { |
|
926 |
- RINOK(SzSkeepDataSize(sd, size)); |
|
927 |
- } |
|
928 |
- else |
|
929 |
- switch((int)type) |
|
930 |
- { |
|
931 |
- case k7zIdName: |
|
932 |
- { |
|
933 |
- RINOK(SzReadSwitch(sd)); |
|
934 |
- RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) |
|
935 |
- break; |
|
936 |
- } |
|
937 |
- case k7zIdEmptyStream: |
|
938 |
- { |
|
939 |
- RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); |
|
940 |
- numEmptyStreams = 0; |
|
941 |
- for (i = 0; i < numFiles; i++) |
|
942 |
- if ((*emptyStreamVector)[i]) |
|
943 |
- numEmptyStreams++; |
|
944 |
- break; |
|
945 |
- } |
|
946 |
- case k7zIdEmptyFile: |
|
947 |
- { |
|
948 |
- RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); |
|
949 |
- break; |
|
950 |
- } |
|
951 |
- case k7zIdMTime: |
|
952 |
- { |
|
953 |
- RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); |
|
954 |
- RINOK(SzReadSwitch(sd)); |
|
955 |
- for (i = 0; i < numFiles; i++) |
|
956 |
- { |
|
957 |
- CSzFileItem *f = &files[i]; |
|
958 |
- Byte defined = (*lwtVector)[i]; |
|
959 |
- f->MTimeDefined = defined; |
|
960 |
- f->MTime.Low = f->MTime.High = 0; |
|
961 |
- if (defined) |
|
962 |
- { |
|
963 |
- RINOK(SzReadUInt32(sd, &f->MTime.Low)); |
|
964 |
- RINOK(SzReadUInt32(sd, &f->MTime.High)); |
|
965 |
- } |
|
966 |
- } |
|
967 |
- break; |
|
968 |
- } |
|
969 |
- default: |
|
970 |
- { |
|
971 |
- RINOK(SzSkeepDataSize(sd, size)); |
|
972 |
- } |
|
973 |
- } |
|
974 |
- } |
|
975 |
- |
|
976 |
- { |
|
977 |
- UInt32 emptyFileIndex = 0; |
|
978 |
- UInt32 sizeIndex = 0; |
|
979 |
- for (i = 0; i < numFiles; i++) |
|
980 |
- { |
|
981 |
- CSzFileItem *file = files + i; |
|
982 |
- file->IsAnti = 0; |
|
983 |
- if (*emptyStreamVector == 0) |
|
984 |
- file->HasStream = 1; |
|
985 |
- else |
|
986 |
- file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); |
|
987 |
- if (file->HasStream) |
|
988 |
- { |
|
989 |
- file->IsDir = 0; |
|
990 |
- file->Size = (*unpackSizes)[sizeIndex]; |
|
991 |
- file->FileCRC = (*digests)[sizeIndex]; |
|
992 |
- file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; |
|
993 |
- sizeIndex++; |
|
994 |
- } |
|
995 |
- else |
|
996 |
- { |
|
997 |
- if (*emptyFileVector == 0) |
|
998 |
- file->IsDir = 1; |
|
999 |
- else |
|
1000 |
- file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); |
|
1001 |
- emptyFileIndex++; |
|
1002 |
- file->Size = 0; |
|
1003 |
- file->FileCRCDefined = 0; |
|
1004 |
- } |
|
1005 |
- } |
|
1006 |
- } |
|
1007 |
- return SzArEx_Fill(p, allocMain); |
|
1008 |
-} |
|
1009 |
- |
|
1010 |
-static SRes SzReadHeader( |
|
1011 |
- CSzArEx *p, |
|
1012 |
- CSzData *sd, |
|
1013 |
- ISzAlloc *allocMain, |
|
1014 |
- ISzAlloc *allocTemp) |
|
1015 |
-{ |
|
1016 |
- UInt64 *unpackSizes = 0; |
|
1017 |
- Byte *digestsDefined = 0; |
|
1018 |
- UInt32 *digests = 0; |
|
1019 |
- Byte *emptyStreamVector = 0; |
|
1020 |
- Byte *emptyFileVector = 0; |
|
1021 |
- Byte *lwtVector = 0; |
|
1022 |
- SRes res = SzReadHeader2(p, sd, |
|
1023 |
- &unpackSizes, &digestsDefined, &digests, |
|
1024 |
- &emptyStreamVector, &emptyFileVector, &lwtVector, |
|
1025 |
- allocMain, allocTemp); |
|
1026 |
- IAlloc_Free(allocTemp, unpackSizes); |
|
1027 |
- IAlloc_Free(allocTemp, digestsDefined); |
|
1028 |
- IAlloc_Free(allocTemp, digests); |
|
1029 |
- IAlloc_Free(allocTemp, emptyStreamVector); |
|
1030 |
- IAlloc_Free(allocTemp, emptyFileVector); |
|
1031 |
- IAlloc_Free(allocTemp, lwtVector); |
|
1032 |
- return res; |
|
1033 |
-} |
|
1034 |
- |
|
1035 |
-static SRes SzReadAndDecodePackedStreams2( |
|
1036 |
- ILookInStream *inStream, |
|
1037 |
- CSzData *sd, |
|
1038 |
- CBuf *outBuffer, |
|
1039 |
- UInt64 baseOffset, |
|
1040 |
- CSzAr *p, |
|
1041 |
- UInt64 **unpackSizes, |
|
1042 |
- Byte **digestsDefined, |
|
1043 |
- UInt32 **digests, |
|
1044 |
- ISzAlloc *allocTemp) |
|
1045 |
-{ |
|
1046 |
- |
|
1047 |
- UInt32 numUnpackStreams = 0; |
|
1048 |
- UInt64 dataStartPos; |
|
1049 |
- CSzFolder *folder; |
|
1050 |
- UInt64 unpackSize; |
|
1051 |
- SRes res; |
|
1052 |
- |
|
1053 |
- RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, |
|
1054 |
- &numUnpackStreams, unpackSizes, digestsDefined, digests, |
|
1055 |
- allocTemp, allocTemp)); |
|
1056 |
- |
|
1057 |
- dataStartPos += baseOffset; |
|
1058 |
- if (p->NumFolders != 1) |
|
1059 |
- return SZ_ERROR_ARCHIVE; |
|
1060 |
- |
|
1061 |
- folder = p->Folders; |
|
1062 |
- unpackSize = SzFolder_GetUnpackSize(folder); |
|
1063 |
- |
|
1064 |
- RINOK(LookInStream_SeekTo(inStream, dataStartPos)); |
|
1065 |
- |
|
1066 |
- if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) |
|
1067 |
- return SZ_ERROR_MEM; |
|
1068 |
- |
|
1069 |
- res = SzDecode(p->PackSizes, folder, |
|
1070 |
- inStream, dataStartPos, |
|
1071 |
- outBuffer->data, (size_t)unpackSize, allocTemp); |
|
1072 |
- RINOK(res); |
|
1073 |
- if (folder->UnpackCRCDefined) |
|
1074 |
- if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) |
|
1075 |
- return SZ_ERROR_CRC; |
|
1076 |
- return SZ_OK; |
|
1077 |
-} |
|
1078 |
- |
|
1079 |
-static SRes SzReadAndDecodePackedStreams( |
|
1080 |
- ILookInStream *inStream, |
|
1081 |
- CSzData *sd, |
|
1082 |
- CBuf *outBuffer, |
|
1083 |
- UInt64 baseOffset, |
|
1084 |
- ISzAlloc *allocTemp) |
|
1085 |
-{ |
|
1086 |
- CSzAr p; |
|
1087 |
- UInt64 *unpackSizes = 0; |
|
1088 |
- Byte *digestsDefined = 0; |
|
1089 |
- UInt32 *digests = 0; |
|
1090 |
- SRes res; |
|
1091 |
- SzAr_Init(&p); |
|
1092 |
- res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, |
|
1093 |
- &p, &unpackSizes, &digestsDefined, &digests, |
|
1094 |
- allocTemp); |
|
1095 |
- SzAr_Free(&p, allocTemp); |
|
1096 |
- IAlloc_Free(allocTemp, unpackSizes); |
|
1097 |
- IAlloc_Free(allocTemp, digestsDefined); |
|
1098 |
- IAlloc_Free(allocTemp, digests); |
|
1099 |
- return res; |
|
1100 |
-} |
|
1101 |
- |
|
1102 |
-static SRes SzArEx_Open2( |
|
1103 |
- CSzArEx *p, |
|
1104 |
- ILookInStream *inStream, |
|
1105 |
- ISzAlloc *allocMain, |
|
1106 |
- ISzAlloc *allocTemp) |
|
1107 |
-{ |
|
1108 |
- Byte header[k7zStartHeaderSize]; |
|
1109 |
- UInt64 nextHeaderOffset, nextHeaderSize; |
|
1110 |
- size_t nextHeaderSizeT; |
|
1111 |
- UInt32 nextHeaderCRC; |
|
1112 |
- CBuf buffer; |
|
1113 |
- SRes res; |
|
1114 |
- |
|
1115 |
- RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); |
|
1116 |
- |
|
1117 |
- if (!TestSignatureCandidate(header)) |
|
1118 |
- return SZ_ERROR_NO_ARCHIVE; |
|
1119 |
- if (header[6] != k7zMajorVersion) |
|
1120 |
- return SZ_ERROR_UNSUPPORTED; |
|
1121 |
- |
|
1122 |
- nextHeaderOffset = GetUi64(header + 12); |
|
1123 |
- nextHeaderSize = GetUi64(header + 20); |
|
1124 |
- nextHeaderCRC = GetUi32(header + 28); |
|
1125 |
- |
|
1126 |
- p->startPosAfterHeader = k7zStartHeaderSize; |
|
1127 |
- |
|
1128 |
- if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) |
|
1129 |
- return SZ_ERROR_CRC; |
|
1130 |
- |
|
1131 |
- nextHeaderSizeT = (size_t)nextHeaderSize; |
|
1132 |
- if (nextHeaderSizeT != nextHeaderSize) |
|
1133 |
- return SZ_ERROR_MEM; |
|
1134 |
- if (nextHeaderSizeT == 0) |
|
1135 |
- return SZ_OK; |
|
1136 |
- if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || |
|
1137 |
- nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) |
|
1138 |
- return SZ_ERROR_NO_ARCHIVE; |
|
1139 |
- |
|
1140 |
- { |
|
1141 |
- Int64 pos = 0; |
|
1142 |
- RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); |
|
1143 |
- if ((UInt64)pos < nextHeaderOffset || |
|
1144 |
- (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || |
|
1145 |
- (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) |
|
1146 |
- return SZ_ERROR_INPUT_EOF; |
|
1147 |
- } |
|
1148 |
- |
|
1149 |
- RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); |
|
1150 |
- |
|
1151 |
- if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) |
|
1152 |
- return SZ_ERROR_MEM; |
|
1153 |
- |
|
1154 |
- res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); |
|
1155 |
- if (res == SZ_OK) |
|
1156 |
- { |
|
1157 |
- res = SZ_ERROR_ARCHIVE; |
|
1158 |
- if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) |
|
1159 |
- { |
|
1160 |
- CSzData sd; |
|
1161 |
- UInt64 type; |
|
1162 |
- sd.Data = buffer.data; |
|
1163 |
- sd.Size = buffer.size; |
|
1164 |
- res = SzReadID(&sd, &type); |
|
1165 |
- if (res == SZ_OK) |
|
1166 |
- { |
|
1167 |
- if (type == k7zIdEncodedHeader) |
|
1168 |
- { |
|
1169 |
- CBuf outBuffer; |
|
1170 |
- Buf_Init(&outBuffer); |
|
1171 |
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); |
|
1172 |
- if (res != SZ_OK) |
|
1173 |
- Buf_Free(&outBuffer, allocTemp); |
|
1174 |
- else |
|
1175 |
- { |
|
1176 |
- Buf_Free(&buffer, allocTemp); |
|
1177 |
- buffer.data = outBuffer.data; |
|
1178 |
- buffer.size = outBuffer.size; |
|
1179 |
- sd.Data = buffer.data; |
|
1180 |
- sd.Size = buffer.size; |
|
1181 |
- res = SzReadID(&sd, &type); |
|
1182 |
- } |
|
1183 |
- } |
|
1184 |
- } |
|
1185 |
- if (res == SZ_OK) |
|
1186 |
- { |
|
1187 |
- if (type == k7zIdHeader) |
|
1188 |
- res = SzReadHeader(p, &sd, allocMain, allocTemp); |
|
1189 |
- else |
|
1190 |
- res = SZ_ERROR_UNSUPPORTED; |
|
1191 |
- } |
|
1192 |
- } |
|
1193 |
- } |
|
1194 |
- Buf_Free(&buffer, allocTemp); |
|
1195 |
- return res; |
|
1196 |
-} |
|
1197 |
- |
|
1198 |
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) |
|
1199 |
-{ |
|
1200 |
- SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); |
|
1201 |
- if (res != SZ_OK) |
|
1202 |
- SzArEx_Free(p, allocMain); |
|
1203 |
- return res; |
|
1204 |
-} |
|
1 |
+/* 7zIn.c -- 7z Input functions |
|
2 |
+2008-12-31 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "../../7zCrc.h" |
|
5 |
+#include "../../CpuArch.h" |
|
6 |
+ |
|
7 |
+#include "7zDecode.h" |
|
8 |
+#include "7zIn.h" |
|
9 |
+ |
|
10 |
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } |
|
11 |
+ |
|
12 |
+#define NUM_FOLDER_CODERS_MAX 32 |
|
13 |
+#define NUM_CODER_STREAMS_MAX 32 |
|
14 |
+ |
|
15 |
+void SzArEx_Init(CSzArEx *p) |
|
16 |
+{ |
|
17 |
+ SzAr_Init(&p->db); |
|
18 |
+ p->FolderStartPackStreamIndex = 0; |
|
19 |
+ p->PackStreamStartPositions = 0; |
|
20 |
+ p->FolderStartFileIndex = 0; |
|
21 |
+ p->FileIndexToFolderIndexMap = 0; |
|
22 |
+} |
|
23 |
+ |
|
24 |
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) |
|
25 |
+{ |
|
26 |
+ IAlloc_Free(alloc, p->FolderStartPackStreamIndex); |
|
27 |
+ IAlloc_Free(alloc, p->PackStreamStartPositions); |
|
28 |
+ IAlloc_Free(alloc, p->FolderStartFileIndex); |
|
29 |
+ IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); |
|
30 |
+ SzAr_Free(&p->db, alloc); |
|
31 |
+ SzArEx_Init(p); |
|
32 |
+} |
|
33 |
+ |
|
34 |
+/* |
|
35 |
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const |
|
36 |
+{ |
|
37 |
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; |
|
38 |
+} |
|
39 |
+ |
|
40 |
+UInt64 GetFilePackSize(int fileIndex) const |
|
41 |
+{ |
|
42 |
+ int folderIndex = FileIndexToFolderIndexMap[fileIndex]; |
|
43 |
+ if (folderIndex >= 0) |
|
44 |
+ { |
|
45 |
+ const CSzFolder &folderInfo = Folders[folderIndex]; |
|
46 |
+ if (FolderStartFileIndex[folderIndex] == fileIndex) |
|
47 |
+ return GetFolderFullPackSize(folderIndex); |
|
48 |
+ } |
|
49 |
+ return 0; |
|
50 |
+} |
|
51 |
+*/ |
|
52 |
+ |
|
53 |
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ |
|
54 |
+ if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } |
|
55 |
+ |
|
56 |
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) |
|
57 |
+{ |
|
58 |
+ UInt32 startPos = 0; |
|
59 |
+ UInt64 startPosSize = 0; |
|
60 |
+ UInt32 i; |
|
61 |
+ UInt32 folderIndex = 0; |
|
62 |
+ UInt32 indexInFolder = 0; |
|
63 |
+ MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); |
|
64 |
+ for (i = 0; i < p->db.NumFolders; i++) |
|
65 |
+ { |
|
66 |
+ p->FolderStartPackStreamIndex[i] = startPos; |
|
67 |
+ startPos += p->db.Folders[i].NumPackStreams; |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+ MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); |
|
71 |
+ |
|
72 |
+ for (i = 0; i < p->db.NumPackStreams; i++) |
|
73 |
+ { |
|
74 |
+ p->PackStreamStartPositions[i] = startPosSize; |
|
75 |
+ startPosSize += p->db.PackSizes[i]; |
|
76 |
+ } |
|
77 |
+ |
|
78 |
+ MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); |
|
79 |
+ MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); |
|
80 |
+ |
|
81 |
+ for (i = 0; i < p->db.NumFiles; i++) |
|
82 |
+ { |
|
83 |
+ CSzFileItem *file = p->db.Files + i; |
|
84 |
+ int emptyStream = !file->HasStream; |
|
85 |
+ if (emptyStream && indexInFolder == 0) |
|
86 |
+ { |
|
87 |
+ p->FileIndexToFolderIndexMap[i] = (UInt32)-1; |
|
88 |
+ continue; |
|
89 |
+ } |
|
90 |
+ if (indexInFolder == 0) |
|
91 |
+ { |
|
92 |
+ /* |
|
93 |
+ v3.13 incorrectly worked with empty folders |
|
94 |
+ v4.07: Loop for skipping empty folders |
|
95 |
+ */ |
|
96 |
+ for (;;) |
|
97 |
+ { |
|
98 |
+ if (folderIndex >= p->db.NumFolders) |
|
99 |
+ return SZ_ERROR_ARCHIVE; |
|
100 |
+ p->FolderStartFileIndex[folderIndex] = i; |
|
101 |
+ if (p->db.Folders[folderIndex].NumUnpackStreams != 0) |
|
102 |
+ break; |
|
103 |
+ folderIndex++; |
|
104 |
+ } |
|
105 |
+ } |
|
106 |
+ p->FileIndexToFolderIndexMap[i] = folderIndex; |
|
107 |
+ if (emptyStream) |
|
108 |
+ continue; |
|
109 |
+ indexInFolder++; |
|
110 |
+ if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) |
|
111 |
+ { |
|
112 |
+ folderIndex++; |
|
113 |
+ indexInFolder = 0; |
|
114 |
+ } |
|
115 |
+ } |
|
116 |
+ return SZ_OK; |
|
117 |
+} |
|
118 |
+ |
|
119 |
+ |
|
120 |
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) |
|
121 |
+{ |
|
122 |
+ return p->dataPos + |
|
123 |
+ p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; |
|
124 |
+} |
|
125 |
+ |
|
126 |
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) |
|
127 |
+{ |
|
128 |
+ UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; |
|
129 |
+ CSzFolder *folder = p->db.Folders + folderIndex; |
|
130 |
+ UInt64 size = 0; |
|
131 |
+ UInt32 i; |
|
132 |
+ for (i = 0; i < folder->NumPackStreams; i++) |
|
133 |
+ { |
|
134 |
+ UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; |
|
135 |
+ if (t < size) /* check it */ |
|
136 |
+ return SZ_ERROR_FAIL; |
|
137 |
+ size = t; |
|
138 |
+ } |
|
139 |
+ *resSize = size; |
|
140 |
+ return SZ_OK; |
|
141 |
+} |
|
142 |
+ |
|
143 |
+ |
|
144 |
+/* |
|
145 |
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector, |
|
146 |
+ CObjectVector<CSzFileItem> &files, UInt64 type) |
|
147 |
+{ |
|
148 |
+ CBoolVector boolVector; |
|
149 |
+ RINOK(ReadBoolVector2(files.Size(), boolVector)) |
|
150 |
+ |
|
151 |
+ CStreamSwitch streamSwitch; |
|
152 |
+ RINOK(streamSwitch.Set(this, &dataVector)); |
|
153 |
+ |
|
154 |
+ for (int i = 0; i < files.Size(); i++) |
|
155 |
+ { |
|
156 |
+ CSzFileItem &file = files[i]; |
|
157 |
+ CArchiveFileTime fileTime; |
|
158 |
+ bool defined = boolVector[i]; |
|
159 |
+ if (defined) |
|
160 |
+ { |
|
161 |
+ UInt32 low, high; |
|
162 |
+ RINOK(SzReadUInt32(low)); |
|
163 |
+ RINOK(SzReadUInt32(high)); |
|
164 |
+ fileTime.dwLowDateTime = low; |
|
165 |
+ fileTime.dwHighDateTime = high; |
|
166 |
+ } |
|
167 |
+ switch(type) |
|
168 |
+ { |
|
169 |
+ case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; |
|
170 |
+ case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; |
|
171 |
+ case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; |
|
172 |
+ } |
|
173 |
+ } |
|
174 |
+ return SZ_OK; |
|
175 |
+} |
|
176 |
+*/ |
|
177 |
+ |
|
178 |
+static int TestSignatureCandidate(Byte *testBytes) |
|
179 |
+{ |
|
180 |
+ size_t i; |
|
181 |
+ for (i = 0; i < k7zSignatureSize; i++) |
|
182 |
+ if (testBytes[i] != k7zSignature[i]) |
|
183 |
+ return 0; |
|
184 |
+ return 1; |
|
185 |
+} |
|
186 |
+ |
|
187 |
+typedef struct _CSzState |
|
188 |
+{ |
|
189 |
+ Byte *Data; |
|
190 |
+ size_t Size; |
|
191 |
+}CSzData; |
|
192 |
+ |
|
193 |
+static SRes SzReadByte(CSzData *sd, Byte *b) |
|
194 |
+{ |
|
195 |
+ if (sd->Size == 0) |
|
196 |
+ return SZ_ERROR_ARCHIVE; |
|
197 |
+ sd->Size--; |
|
198 |
+ *b = *sd->Data++; |
|
199 |
+ return SZ_OK; |
|
200 |
+} |
|
201 |
+ |
|
202 |
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) |
|
203 |
+{ |
|
204 |
+ size_t i; |
|
205 |
+ for (i = 0; i < size; i++) |
|
206 |
+ { |
|
207 |
+ RINOK(SzReadByte(sd, data + i)); |
|
208 |
+ } |
|
209 |
+ return SZ_OK; |
|
210 |
+} |
|
211 |
+ |
|
212 |
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value) |
|
213 |
+{ |
|
214 |
+ int i; |
|
215 |
+ *value = 0; |
|
216 |
+ for (i = 0; i < 4; i++) |
|
217 |
+ { |
|
218 |
+ Byte b; |
|
219 |
+ RINOK(SzReadByte(sd, &b)); |
|
220 |
+ *value |= ((UInt32)(b) << (8 * i)); |
|
221 |
+ } |
|
222 |
+ return SZ_OK; |
|
223 |
+} |
|
224 |
+ |
|
225 |
+static SRes SzReadNumber(CSzData *sd, UInt64 *value) |
|
226 |
+{ |
|
227 |
+ Byte firstByte; |
|
228 |
+ Byte mask = 0x80; |
|
229 |
+ int i; |
|
230 |
+ RINOK(SzReadByte(sd, &firstByte)); |
|
231 |
+ *value = 0; |
|
232 |
+ for (i = 0; i < 8; i++) |
|
233 |
+ { |
|
234 |
+ Byte b; |
|
235 |
+ if ((firstByte & mask) == 0) |
|
236 |
+ { |
|
237 |
+ UInt64 highPart = firstByte & (mask - 1); |
|
238 |
+ *value += (highPart << (8 * i)); |
|
239 |
+ return SZ_OK; |
|
240 |
+ } |
|
241 |
+ RINOK(SzReadByte(sd, &b)); |
|
242 |
+ *value |= ((UInt64)b << (8 * i)); |
|
243 |
+ mask >>= 1; |
|
244 |
+ } |
|
245 |
+ return SZ_OK; |
|
246 |
+} |
|
247 |
+ |
|
248 |
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value) |
|
249 |
+{ |
|
250 |
+ UInt64 value64; |
|
251 |
+ RINOK(SzReadNumber(sd, &value64)); |
|
252 |
+ if (value64 >= 0x80000000) |
|
253 |
+ return SZ_ERROR_UNSUPPORTED; |
|
254 |
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) |
|
255 |
+ return SZ_ERROR_UNSUPPORTED; |
|
256 |
+ *value = (UInt32)value64; |
|
257 |
+ return SZ_OK; |
|
258 |
+} |
|
259 |
+ |
|
260 |
+static SRes SzReadID(CSzData *sd, UInt64 *value) |
|
261 |
+{ |
|
262 |
+ return SzReadNumber(sd, value); |
|
263 |
+} |
|
264 |
+ |
|
265 |
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) |
|
266 |
+{ |
|
267 |
+ if (size > sd->Size) |
|
268 |
+ return SZ_ERROR_ARCHIVE; |
|
269 |
+ sd->Size -= (size_t)size; |
|
270 |
+ sd->Data += (size_t)size; |
|
271 |
+ return SZ_OK; |
|
272 |
+} |
|
273 |
+ |
|
274 |
+static SRes SzSkeepData(CSzData *sd) |
|
275 |
+{ |
|
276 |
+ UInt64 size; |
|
277 |
+ RINOK(SzReadNumber(sd, &size)); |
|
278 |
+ return SzSkeepDataSize(sd, size); |
|
279 |
+} |
|
280 |
+ |
|
281 |
+static SRes SzReadArchiveProperties(CSzData *sd) |
|
282 |
+{ |
|
283 |
+ for (;;) |
|
284 |
+ { |
|
285 |
+ UInt64 type; |
|
286 |
+ RINOK(SzReadID(sd, &type)); |
|
287 |
+ if (type == k7zIdEnd) |
|
288 |
+ break; |
|
289 |
+ SzSkeepData(sd); |
|
290 |
+ } |
|
291 |
+ return SZ_OK; |
|
292 |
+} |
|
293 |
+ |
|
294 |
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) |
|
295 |
+{ |
|
296 |
+ for (;;) |
|
297 |
+ { |
|
298 |
+ UInt64 type; |
|
299 |
+ RINOK(SzReadID(sd, &type)); |
|
300 |
+ if (type == attribute) |
|
301 |
+ return SZ_OK; |
|
302 |
+ if (type == k7zIdEnd) |
|
303 |
+ return SZ_ERROR_ARCHIVE; |
|
304 |
+ RINOK(SzSkeepData(sd)); |
|
305 |
+ } |
|
306 |
+} |
|
307 |
+ |
|
308 |
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
309 |
+{ |
|
310 |
+ Byte b = 0; |
|
311 |
+ Byte mask = 0; |
|
312 |
+ size_t i; |
|
313 |
+ MY_ALLOC(Byte, *v, numItems, alloc); |
|
314 |
+ for (i = 0; i < numItems; i++) |
|
315 |
+ { |
|
316 |
+ if (mask == 0) |
|
317 |
+ { |
|
318 |
+ RINOK(SzReadByte(sd, &b)); |
|
319 |
+ mask = 0x80; |
|
320 |
+ } |
|
321 |
+ (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); |
|
322 |
+ mask >>= 1; |
|
323 |
+ } |
|
324 |
+ return SZ_OK; |
|
325 |
+} |
|
326 |
+ |
|
327 |
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
328 |
+{ |
|
329 |
+ Byte allAreDefined; |
|
330 |
+ size_t i; |
|
331 |
+ RINOK(SzReadByte(sd, &allAreDefined)); |
|
332 |
+ if (allAreDefined == 0) |
|
333 |
+ return SzReadBoolVector(sd, numItems, v, alloc); |
|
334 |
+ MY_ALLOC(Byte, *v, numItems, alloc); |
|
335 |
+ for (i = 0; i < numItems; i++) |
|
336 |
+ (*v)[i] = 1; |
|
337 |
+ return SZ_OK; |
|
338 |
+} |
|
339 |
+ |
|
340 |
+static SRes SzReadHashDigests( |
|
341 |
+ CSzData *sd, |
|
342 |
+ size_t numItems, |
|
343 |
+ Byte **digestsDefined, |
|
344 |
+ UInt32 **digests, |
|
345 |
+ ISzAlloc *alloc) |
|
346 |
+{ |
|
347 |
+ size_t i; |
|
348 |
+ RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); |
|
349 |
+ MY_ALLOC(UInt32, *digests, numItems, alloc); |
|
350 |
+ for (i = 0; i < numItems; i++) |
|
351 |
+ if ((*digestsDefined)[i]) |
|
352 |
+ { |
|
353 |
+ RINOK(SzReadUInt32(sd, (*digests) + i)); |
|
354 |
+ } |
|
355 |
+ return SZ_OK; |
|
356 |
+} |
|
357 |
+ |
|
358 |
+static SRes SzReadPackInfo( |
|
359 |
+ CSzData *sd, |
|
360 |
+ UInt64 *dataOffset, |
|
361 |
+ UInt32 *numPackStreams, |
|
362 |
+ UInt64 **packSizes, |
|
363 |
+ Byte **packCRCsDefined, |
|
364 |
+ UInt32 **packCRCs, |
|
365 |
+ ISzAlloc *alloc) |
|
366 |
+{ |
|
367 |
+ UInt32 i; |
|
368 |
+ RINOK(SzReadNumber(sd, dataOffset)); |
|
369 |
+ RINOK(SzReadNumber32(sd, numPackStreams)); |
|
370 |
+ |
|
371 |
+ RINOK(SzWaitAttribute(sd, k7zIdSize)); |
|
372 |
+ |
|
373 |
+ MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); |
|
374 |
+ |
|
375 |
+ for (i = 0; i < *numPackStreams; i++) |
|
376 |
+ { |
|
377 |
+ RINOK(SzReadNumber(sd, (*packSizes) + i)); |
|
378 |
+ } |
|
379 |
+ |
|
380 |
+ for (;;) |
|
381 |
+ { |
|
382 |
+ UInt64 type; |
|
383 |
+ RINOK(SzReadID(sd, &type)); |
|
384 |
+ if (type == k7zIdEnd) |
|
385 |
+ break; |
|
386 |
+ if (type == k7zIdCRC) |
|
387 |
+ { |
|
388 |
+ RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); |
|
389 |
+ continue; |
|
390 |
+ } |
|
391 |
+ RINOK(SzSkeepData(sd)); |
|
392 |
+ } |
|
393 |
+ if (*packCRCsDefined == 0) |
|
394 |
+ { |
|
395 |
+ MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); |
|
396 |
+ MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); |
|
397 |
+ for (i = 0; i < *numPackStreams; i++) |
|
398 |
+ { |
|
399 |
+ (*packCRCsDefined)[i] = 0; |
|
400 |
+ (*packCRCs)[i] = 0; |
|
401 |
+ } |
|
402 |
+ } |
|
403 |
+ return SZ_OK; |
|
404 |
+} |
|
405 |
+ |
|
406 |
+static SRes SzReadSwitch(CSzData *sd) |
|
407 |
+{ |
|
408 |
+ Byte external; |
|
409 |
+ RINOK(SzReadByte(sd, &external)); |
|
410 |
+ return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; |
|
411 |
+} |
|
412 |
+ |
|
413 |
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) |
|
414 |
+{ |
|
415 |
+ UInt32 numCoders, numBindPairs, numPackStreams, i; |
|
416 |
+ UInt32 numInStreams = 0, numOutStreams = 0; |
|
417 |
+ |
|
418 |
+ RINOK(SzReadNumber32(sd, &numCoders)); |
|
419 |
+ if (numCoders > NUM_FOLDER_CODERS_MAX) |
|
420 |
+ return SZ_ERROR_UNSUPPORTED; |
|
421 |
+ folder->NumCoders = numCoders; |
|
422 |
+ |
|
423 |
+ MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); |
|
424 |
+ |
|
425 |
+ for (i = 0; i < numCoders; i++) |
|
426 |
+ SzCoderInfo_Init(folder->Coders + i); |
|
427 |
+ |
|
428 |
+ for (i = 0; i < numCoders; i++) |
|
429 |
+ { |
|
430 |
+ Byte mainByte; |
|
431 |
+ CSzCoderInfo *coder = folder->Coders + i; |
|
432 |
+ { |
|
433 |
+ unsigned idSize, j; |
|
434 |
+ Byte longID[15]; |
|
435 |
+ RINOK(SzReadByte(sd, &mainByte)); |
|
436 |
+ idSize = (unsigned)(mainByte & 0xF); |
|
437 |
+ RINOK(SzReadBytes(sd, longID, idSize)); |
|
438 |
+ if (idSize > sizeof(coder->MethodID)) |
|
439 |
+ return SZ_ERROR_UNSUPPORTED; |
|
440 |
+ coder->MethodID = 0; |
|
441 |
+ for (j = 0; j < idSize; j++) |
|
442 |
+ coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); |
|
443 |
+ |
|
444 |
+ if ((mainByte & 0x10) != 0) |
|
445 |
+ { |
|
446 |
+ RINOK(SzReadNumber32(sd, &coder->NumInStreams)); |
|
447 |
+ RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); |
|
448 |
+ if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || |
|
449 |
+ coder->NumOutStreams > NUM_CODER_STREAMS_MAX) |
|
450 |
+ return SZ_ERROR_UNSUPPORTED; |
|
451 |
+ } |
|
452 |
+ else |
|
453 |
+ { |
|
454 |
+ coder->NumInStreams = 1; |
|
455 |
+ coder->NumOutStreams = 1; |
|
456 |
+ } |
|
457 |
+ if ((mainByte & 0x20) != 0) |
|
458 |
+ { |
|
459 |
+ UInt64 propertiesSize = 0; |
|
460 |
+ RINOK(SzReadNumber(sd, &propertiesSize)); |
|
461 |
+ if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) |
|
462 |
+ return SZ_ERROR_MEM; |
|
463 |
+ RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); |
|
464 |
+ } |
|
465 |
+ } |
|
466 |
+ while ((mainByte & 0x80) != 0) |
|
467 |
+ { |
|
468 |
+ RINOK(SzReadByte(sd, &mainByte)); |
|
469 |
+ RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); |
|
470 |
+ if ((mainByte & 0x10) != 0) |
|
471 |
+ { |
|
472 |
+ UInt32 n; |
|
473 |
+ RINOK(SzReadNumber32(sd, &n)); |
|
474 |
+ RINOK(SzReadNumber32(sd, &n)); |
|
475 |
+ } |
|
476 |
+ if ((mainByte & 0x20) != 0) |
|
477 |
+ { |
|
478 |
+ UInt64 propertiesSize = 0; |
|
479 |
+ RINOK(SzReadNumber(sd, &propertiesSize)); |
|
480 |
+ RINOK(SzSkeepDataSize(sd, propertiesSize)); |
|
481 |
+ } |
|
482 |
+ } |
|
483 |
+ numInStreams += coder->NumInStreams; |
|
484 |
+ numOutStreams += coder->NumOutStreams; |
|
485 |
+ } |
|
486 |
+ |
|
487 |
+ if (numOutStreams == 0) |
|
488 |
+ return SZ_ERROR_UNSUPPORTED; |
|
489 |
+ |
|
490 |
+ folder->NumBindPairs = numBindPairs = numOutStreams - 1; |
|
491 |
+ MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); |
|
492 |
+ |
|
493 |
+ for (i = 0; i < numBindPairs; i++) |
|
494 |
+ { |
|
495 |
+ CBindPair *bp = folder->BindPairs + i; |
|
496 |
+ RINOK(SzReadNumber32(sd, &bp->InIndex)); |
|
497 |
+ RINOK(SzReadNumber32(sd, &bp->OutIndex)); |
|
498 |
+ } |
|
499 |
+ |
|
500 |
+ if (numInStreams < numBindPairs) |
|
501 |
+ return SZ_ERROR_UNSUPPORTED; |
|
502 |
+ |
|
503 |
+ folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; |
|
504 |
+ MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); |
|
505 |
+ |
|
506 |
+ if (numPackStreams == 1) |
|
507 |
+ { |
|
508 |
+ for (i = 0; i < numInStreams ; i++) |
|
509 |
+ if (SzFolder_FindBindPairForInStream(folder, i) < 0) |
|
510 |
+ break; |
|
511 |
+ if (i == numInStreams) |
|
512 |
+ return SZ_ERROR_UNSUPPORTED; |
|
513 |
+ folder->PackStreams[0] = i; |
|
514 |
+ } |
|
515 |
+ else |
|
516 |
+ for (i = 0; i < numPackStreams; i++) |
|
517 |
+ { |
|
518 |
+ RINOK(SzReadNumber32(sd, folder->PackStreams + i)); |
|
519 |
+ } |
|
520 |
+ return SZ_OK; |
|
521 |
+} |
|
522 |
+ |
|
523 |
+static SRes SzReadUnpackInfo( |
|
524 |
+ CSzData *sd, |
|
525 |
+ UInt32 *numFolders, |
|
526 |
+ CSzFolder **folders, /* for alloc */ |
|
527 |
+ ISzAlloc *alloc, |
|
528 |
+ ISzAlloc *allocTemp) |
|
529 |
+{ |
|
530 |
+ UInt32 i; |
|
531 |
+ RINOK(SzWaitAttribute(sd, k7zIdFolder)); |
|
532 |
+ RINOK(SzReadNumber32(sd, numFolders)); |
|
533 |
+ { |
|
534 |
+ RINOK(SzReadSwitch(sd)); |
|
535 |
+ |
|
536 |
+ MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); |
|
537 |
+ |
|
538 |
+ for (i = 0; i < *numFolders; i++) |
|
539 |
+ SzFolder_Init((*folders) + i); |
|
540 |
+ |
|
541 |
+ for (i = 0; i < *numFolders; i++) |
|
542 |
+ { |
|
543 |
+ RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); |
|
544 |
+ } |
|
545 |
+ } |
|
546 |
+ |
|
547 |
+ RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); |
|
548 |
+ |
|
549 |
+ for (i = 0; i < *numFolders; i++) |
|
550 |
+ { |
|
551 |
+ UInt32 j; |
|
552 |
+ CSzFolder *folder = (*folders) + i; |
|
553 |
+ UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); |
|
554 |
+ |
|
555 |
+ MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); |
|
556 |
+ |
|
557 |
+ for (j = 0; j < numOutStreams; j++) |
|
558 |
+ { |
|
559 |
+ RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); |
|
560 |
+ } |
|
561 |
+ } |
|
562 |
+ |
|
563 |
+ for (;;) |
|
564 |
+ { |
|
565 |
+ UInt64 type; |
|
566 |
+ RINOK(SzReadID(sd, &type)); |
|
567 |
+ if (type == k7zIdEnd) |
|
568 |
+ return SZ_OK; |
|
569 |
+ if (type == k7zIdCRC) |
|
570 |
+ { |
|
571 |
+ SRes res; |
|
572 |
+ Byte *crcsDefined = 0; |
|
573 |
+ UInt32 *crcs = 0; |
|
574 |
+ res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); |
|
575 |
+ if (res == SZ_OK) |
|
576 |
+ { |
|
577 |
+ for (i = 0; i < *numFolders; i++) |
|
578 |
+ { |
|
579 |
+ CSzFolder *folder = (*folders) + i; |
|
580 |
+ folder->UnpackCRCDefined = crcsDefined[i]; |
|
581 |
+ folder->UnpackCRC = crcs[i]; |
|
582 |
+ } |
|
583 |
+ } |
|
584 |
+ IAlloc_Free(allocTemp, crcs); |
|
585 |
+ IAlloc_Free(allocTemp, crcsDefined); |
|
586 |
+ RINOK(res); |
|
587 |
+ continue; |
|
588 |
+ } |
|
589 |
+ RINOK(SzSkeepData(sd)); |
|
590 |
+ } |
|
591 |
+} |
|
592 |
+ |
|
593 |
+static SRes SzReadSubStreamsInfo( |
|
594 |
+ CSzData *sd, |
|
595 |
+ UInt32 numFolders, |
|
596 |
+ CSzFolder *folders, |
|
597 |
+ UInt32 *numUnpackStreams, |
|
598 |
+ UInt64 **unpackSizes, |
|
599 |
+ Byte **digestsDefined, |
|
600 |
+ UInt32 **digests, |
|
601 |
+ ISzAlloc *allocTemp) |
|
602 |
+{ |
|
603 |
+ UInt64 type = 0; |
|
604 |
+ UInt32 i; |
|
605 |
+ UInt32 si = 0; |
|
606 |
+ UInt32 numDigests = 0; |
|
607 |
+ |
|
608 |
+ for (i = 0; i < numFolders; i++) |
|
609 |
+ folders[i].NumUnpackStreams = 1; |
|
610 |
+ *numUnpackStreams = numFolders; |
|
611 |
+ |
|
612 |
+ for (;;) |
|
613 |
+ { |
|
614 |
+ RINOK(SzReadID(sd, &type)); |
|
615 |
+ if (type == k7zIdNumUnpackStream) |
|
616 |
+ { |
|
617 |
+ *numUnpackStreams = 0; |
|
618 |
+ for (i = 0; i < numFolders; i++) |
|
619 |
+ { |
|
620 |
+ UInt32 numStreams; |
|
621 |
+ RINOK(SzReadNumber32(sd, &numStreams)); |
|
622 |
+ folders[i].NumUnpackStreams = numStreams; |
|
623 |
+ *numUnpackStreams += numStreams; |
|
624 |
+ } |
|
625 |
+ continue; |
|
626 |
+ } |
|
627 |
+ if (type == k7zIdCRC || type == k7zIdSize) |
|
628 |
+ break; |
|
629 |
+ if (type == k7zIdEnd) |
|
630 |
+ break; |
|
631 |
+ RINOK(SzSkeepData(sd)); |
|
632 |
+ } |
|
633 |
+ |
|
634 |
+ if (*numUnpackStreams == 0) |
|
635 |
+ { |
|
636 |
+ *unpackSizes = 0; |
|
637 |
+ *digestsDefined = 0; |
|
638 |
+ *digests = 0; |
|
639 |
+ } |
|
640 |
+ else |
|
641 |
+ { |
|
642 |
+ *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); |
|
643 |
+ RINOM(*unpackSizes); |
|
644 |
+ *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); |
|
645 |
+ RINOM(*digestsDefined); |
|
646 |
+ *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); |
|
647 |
+ RINOM(*digests); |
|
648 |
+ } |
|
649 |
+ |
|
650 |
+ for (i = 0; i < numFolders; i++) |
|
651 |
+ { |
|
652 |
+ /* |
|
653 |
+ v3.13 incorrectly worked with empty folders |
|
654 |
+ v4.07: we check that folder is empty |
|
655 |
+ */ |
|
656 |
+ UInt64 sum = 0; |
|
657 |
+ UInt32 j; |
|
658 |
+ UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
659 |
+ if (numSubstreams == 0) |
|
660 |
+ continue; |
|
661 |
+ if (type == k7zIdSize) |
|
662 |
+ for (j = 1; j < numSubstreams; j++) |
|
663 |
+ { |
|
664 |
+ UInt64 size; |
|
665 |
+ RINOK(SzReadNumber(sd, &size)); |
|
666 |
+ (*unpackSizes)[si++] = size; |
|
667 |
+ sum += size; |
|
668 |
+ } |
|
669 |
+ (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; |
|
670 |
+ } |
|
671 |
+ if (type == k7zIdSize) |
|
672 |
+ { |
|
673 |
+ RINOK(SzReadID(sd, &type)); |
|
674 |
+ } |
|
675 |
+ |
|
676 |
+ for (i = 0; i < *numUnpackStreams; i++) |
|
677 |
+ { |
|
678 |
+ (*digestsDefined)[i] = 0; |
|
679 |
+ (*digests)[i] = 0; |
|
680 |
+ } |
|
681 |
+ |
|
682 |
+ |
|
683 |
+ for (i = 0; i < numFolders; i++) |
|
684 |
+ { |
|
685 |
+ UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
686 |
+ if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) |
|
687 |
+ numDigests += numSubstreams; |
|
688 |
+ } |
|
689 |
+ |
|
690 |
+ |
|
691 |
+ si = 0; |
|
692 |
+ for (;;) |
|
693 |
+ { |
|
694 |
+ if (type == k7zIdCRC) |
|
695 |
+ { |
|
696 |
+ int digestIndex = 0; |
|
697 |
+ Byte *digestsDefined2 = 0; |
|
698 |
+ UInt32 *digests2 = 0; |
|
699 |
+ SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); |
|
700 |
+ if (res == SZ_OK) |
|
701 |
+ { |
|
702 |
+ for (i = 0; i < numFolders; i++) |
|
703 |
+ { |
|
704 |
+ CSzFolder *folder = folders + i; |
|
705 |
+ UInt32 numSubstreams = folder->NumUnpackStreams; |
|
706 |
+ if (numSubstreams == 1 && folder->UnpackCRCDefined) |
|
707 |
+ { |
|
708 |
+ (*digestsDefined)[si] = 1; |
|
709 |
+ (*digests)[si] = folder->UnpackCRC; |
|
710 |
+ si++; |
|
711 |
+ } |
|
712 |
+ else |
|
713 |
+ { |
|
714 |
+ UInt32 j; |
|
715 |
+ for (j = 0; j < numSubstreams; j++, digestIndex++) |
|
716 |
+ { |
|
717 |
+ (*digestsDefined)[si] = digestsDefined2[digestIndex]; |
|
718 |
+ (*digests)[si] = digests2[digestIndex]; |
|
719 |
+ si++; |
|
720 |
+ } |
|
721 |
+ } |
|
722 |
+ } |
|
723 |
+ } |
|
724 |
+ IAlloc_Free(allocTemp, digestsDefined2); |
|
725 |
+ IAlloc_Free(allocTemp, digests2); |
|
726 |
+ RINOK(res); |
|
727 |
+ } |
|
728 |
+ else if (type == k7zIdEnd) |
|
729 |
+ return SZ_OK; |
|
730 |
+ else |
|
731 |
+ { |
|
732 |
+ RINOK(SzSkeepData(sd)); |
|
733 |
+ } |
|
734 |
+ RINOK(SzReadID(sd, &type)); |
|
735 |
+ } |
|
736 |
+} |
|
737 |
+ |
|
738 |
+ |
|
739 |
+static SRes SzReadStreamsInfo( |
|
740 |
+ CSzData *sd, |
|
741 |
+ UInt64 *dataOffset, |
|
742 |
+ CSzAr *p, |
|
743 |
+ UInt32 *numUnpackStreams, |
|
744 |
+ UInt64 **unpackSizes, /* allocTemp */ |
|
745 |
+ Byte **digestsDefined, /* allocTemp */ |
|
746 |
+ UInt32 **digests, /* allocTemp */ |
|
747 |
+ ISzAlloc *alloc, |
|
748 |
+ ISzAlloc *allocTemp) |
|
749 |
+{ |
|
750 |
+ for (;;) |
|
751 |
+ { |
|
752 |
+ UInt64 type; |
|
753 |
+ RINOK(SzReadID(sd, &type)); |
|
754 |
+ if ((UInt64)(int)type != type) |
|
755 |
+ return SZ_ERROR_UNSUPPORTED; |
|
756 |
+ switch((int)type) |
|
757 |
+ { |
|
758 |
+ case k7zIdEnd: |
|
759 |
+ return SZ_OK; |
|
760 |
+ case k7zIdPackInfo: |
|
761 |
+ { |
|
762 |
+ RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, |
|
763 |
+ &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); |
|
764 |
+ break; |
|
765 |
+ } |
|
766 |
+ case k7zIdUnpackInfo: |
|
767 |
+ { |
|
768 |
+ RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); |
|
769 |
+ break; |
|
770 |
+ } |
|
771 |
+ case k7zIdSubStreamsInfo: |
|
772 |
+ { |
|
773 |
+ RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, |
|
774 |
+ numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); |
|
775 |
+ break; |
|
776 |
+ } |
|
777 |
+ default: |
|
778 |
+ return SZ_ERROR_UNSUPPORTED; |
|
779 |
+ } |
|
780 |
+ } |
|
781 |
+} |
|
782 |
+ |
|
783 |
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; |
|
784 |
+ |
|
785 |
+static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) |
|
786 |
+{ |
|
787 |
+ UInt32 i; |
|
788 |
+ for (i = 0; i < numFiles; i++) |
|
789 |
+ { |
|
790 |
+ UInt32 len = 0; |
|
791 |
+ UInt32 pos = 0; |
|
792 |
+ CSzFileItem *file = files + i; |
|
793 |
+ while (pos + 2 <= sd->Size) |
|
794 |
+ { |
|
795 |
+ int numAdds; |
|
796 |
+ UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); |
|
797 |
+ pos += 2; |
|
798 |
+ len++; |
|
799 |
+ if (value == 0) |
|
800 |
+ break; |
|
801 |
+ if (value < 0x80) |
|
802 |
+ continue; |
|
803 |
+ if (value >= 0xD800 && value < 0xE000) |
|
804 |
+ { |
|
805 |
+ UInt32 c2; |
|
806 |
+ if (value >= 0xDC00) |
|
807 |
+ return SZ_ERROR_ARCHIVE; |
|
808 |
+ if (pos + 2 > sd->Size) |
|
809 |
+ return SZ_ERROR_ARCHIVE; |
|
810 |
+ c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); |
|
811 |
+ pos += 2; |
|
812 |
+ if (c2 < 0xDC00 || c2 >= 0xE000) |
|
813 |
+ return SZ_ERROR_ARCHIVE; |
|
814 |
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00); |
|
815 |
+ } |
|
816 |
+ for (numAdds = 1; numAdds < 5; numAdds++) |
|
817 |
+ if (value < (((UInt32)1) << (numAdds * 5 + 6))) |
|
818 |
+ break; |
|
819 |
+ len += numAdds; |
|
820 |
+ } |
|
821 |
+ |
|
822 |
+ MY_ALLOC(char, file->Name, (size_t)len, alloc); |
|
823 |
+ |
|
824 |
+ len = 0; |
|
825 |
+ while (2 <= sd->Size) |
|
826 |
+ { |
|
827 |
+ int numAdds; |
|
828 |
+ UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); |
|
829 |
+ SzSkeepDataSize(sd, 2); |
|
830 |
+ if (value < 0x80) |
|
831 |
+ { |
|
832 |
+ file->Name[len++] = (char)value; |
|
833 |
+ if (value == 0) |
|
834 |
+ break; |
|
835 |
+ continue; |
|
836 |
+ } |
|
837 |
+ if (value >= 0xD800 && value < 0xE000) |
|
838 |
+ { |
|
839 |
+ UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); |
|
840 |
+ SzSkeepDataSize(sd, 2); |
|
841 |
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00); |
|
842 |
+ } |
|
843 |
+ for (numAdds = 1; numAdds < 5; numAdds++) |
|
844 |
+ if (value < (((UInt32)1) << (numAdds * 5 + 6))) |
|
845 |
+ break; |
|
846 |
+ file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); |
|
847 |
+ do |
|
848 |
+ { |
|
849 |
+ numAdds--; |
|
850 |
+ file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); |
|
851 |
+ } |
|
852 |
+ while (numAdds > 0); |
|
853 |
+ |
|
854 |
+ len += numAdds; |
|
855 |
+ } |
|
856 |
+ } |
|
857 |
+ return SZ_OK; |
|
858 |
+} |
|
859 |
+ |
|
860 |
+static SRes SzReadHeader2( |
|
861 |
+ CSzArEx *p, /* allocMain */ |
|
862 |
+ CSzData *sd, |
|
863 |
+ UInt64 **unpackSizes, /* allocTemp */ |
|
864 |
+ Byte **digestsDefined, /* allocTemp */ |
|
865 |
+ UInt32 **digests, /* allocTemp */ |
|
866 |
+ Byte **emptyStreamVector, /* allocTemp */ |
|
867 |
+ Byte **emptyFileVector, /* allocTemp */ |
|
868 |
+ Byte **lwtVector, /* allocTemp */ |
|
869 |
+ ISzAlloc *allocMain, |
|
870 |
+ ISzAlloc *allocTemp) |
|
871 |
+{ |
|
872 |
+ UInt64 type; |
|
873 |
+ UInt32 numUnpackStreams = 0; |
|
874 |
+ UInt32 numFiles = 0; |
|
875 |
+ CSzFileItem *files = 0; |
|
876 |
+ UInt32 numEmptyStreams = 0; |
|
877 |
+ UInt32 i; |
|
878 |
+ |
|
879 |
+ RINOK(SzReadID(sd, &type)); |
|
880 |
+ |
|
881 |
+ if (type == k7zIdArchiveProperties) |
|
882 |
+ { |
|
883 |
+ RINOK(SzReadArchiveProperties(sd)); |
|
884 |
+ RINOK(SzReadID(sd, &type)); |
|
885 |
+ } |
|
886 |
+ |
|
887 |
+ |
|
888 |
+ if (type == k7zIdMainStreamsInfo) |
|
889 |
+ { |
|
890 |
+ RINOK(SzReadStreamsInfo(sd, |
|
891 |
+ &p->dataPos, |
|
892 |
+ &p->db, |
|
893 |
+ &numUnpackStreams, |
|
894 |
+ unpackSizes, |
|
895 |
+ digestsDefined, |
|
896 |
+ digests, allocMain, allocTemp)); |
|
897 |
+ p->dataPos += p->startPosAfterHeader; |
|
898 |
+ RINOK(SzReadID(sd, &type)); |
|
899 |
+ } |
|
900 |
+ |
|
901 |
+ if (type == k7zIdEnd) |
|
902 |
+ return SZ_OK; |
|
903 |
+ if (type != k7zIdFilesInfo) |
|
904 |
+ return SZ_ERROR_ARCHIVE; |
|
905 |
+ |
|
906 |
+ RINOK(SzReadNumber32(sd, &numFiles)); |
|
907 |
+ p->db.NumFiles = numFiles; |
|
908 |
+ |
|
909 |
+ MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); |
|
910 |
+ |
|
911 |
+ p->db.Files = files; |
|
912 |
+ for (i = 0; i < numFiles; i++) |
|
913 |
+ SzFile_Init(files + i); |
|
914 |
+ |
|
915 |
+ for (;;) |
|
916 |
+ { |
|
917 |
+ UInt64 type; |
|
918 |
+ UInt64 size; |
|
919 |
+ RINOK(SzReadID(sd, &type)); |
|
920 |
+ if (type == k7zIdEnd) |
|
921 |
+ break; |
|
922 |
+ RINOK(SzReadNumber(sd, &size)); |
|
923 |
+ |
|
924 |
+ if ((UInt64)(int)type != type) |
|
925 |
+ { |
|
926 |
+ RINOK(SzSkeepDataSize(sd, size)); |
|
927 |
+ } |
|
928 |
+ else |
|
929 |
+ switch((int)type) |
|
930 |
+ { |
|
931 |
+ case k7zIdName: |
|
932 |
+ { |
|
933 |
+ RINOK(SzReadSwitch(sd)); |
|
934 |
+ RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) |
|
935 |
+ break; |
|
936 |
+ } |
|
937 |
+ case k7zIdEmptyStream: |
|
938 |
+ { |
|
939 |
+ RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); |
|
940 |
+ numEmptyStreams = 0; |
|
941 |
+ for (i = 0; i < numFiles; i++) |
|
942 |
+ if ((*emptyStreamVector)[i]) |
|
943 |
+ numEmptyStreams++; |
|
944 |
+ break; |
|
945 |
+ } |
|
946 |
+ case k7zIdEmptyFile: |
|
947 |
+ { |
|
948 |
+ RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); |
|
949 |
+ break; |
|
950 |
+ } |
|
951 |
+ case k7zIdMTime: |
|
952 |
+ { |
|
953 |
+ RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); |
|
954 |
+ RINOK(SzReadSwitch(sd)); |
|
955 |
+ for (i = 0; i < numFiles; i++) |
|
956 |
+ { |
|
957 |
+ CSzFileItem *f = &files[i]; |
|
958 |
+ Byte defined = (*lwtVector)[i]; |
|
959 |
+ f->MTimeDefined = defined; |
|
960 |
+ f->MTime.Low = f->MTime.High = 0; |
|
961 |
+ if (defined) |
|
962 |
+ { |
|
963 |
+ RINOK(SzReadUInt32(sd, &f->MTime.Low)); |
|
964 |
+ RINOK(SzReadUInt32(sd, &f->MTime.High)); |
|
965 |
+ } |
|
966 |
+ } |
|
967 |
+ break; |
|
968 |
+ } |
|
969 |
+ default: |
|
970 |
+ { |
|
971 |
+ RINOK(SzSkeepDataSize(sd, size)); |
|
972 |
+ } |
|
973 |
+ } |
|
974 |
+ } |
|
975 |
+ |
|
976 |
+ { |
|
977 |
+ UInt32 emptyFileIndex = 0; |
|
978 |
+ UInt32 sizeIndex = 0; |
|
979 |
+ for (i = 0; i < numFiles; i++) |
|
980 |
+ { |
|
981 |
+ CSzFileItem *file = files + i; |
|
982 |
+ file->IsAnti = 0; |
|
983 |
+ if (*emptyStreamVector == 0) |
|
984 |
+ file->HasStream = 1; |
|
985 |
+ else |
|
986 |
+ file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); |
|
987 |
+ if (file->HasStream) |
|
988 |
+ { |
|
989 |
+ file->IsDir = 0; |
|
990 |
+ file->Size = (*unpackSizes)[sizeIndex]; |
|
991 |
+ file->FileCRC = (*digests)[sizeIndex]; |
|
992 |
+ file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; |
|
993 |
+ sizeIndex++; |
|
994 |
+ } |
|
995 |
+ else |
|
996 |
+ { |
|
997 |
+ if (*emptyFileVector == 0) |
|
998 |
+ file->IsDir = 1; |
|
999 |
+ else |
|
1000 |
+ file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); |
|
1001 |
+ emptyFileIndex++; |
|
1002 |
+ file->Size = 0; |
|
1003 |
+ file->FileCRCDefined = 0; |
|
1004 |
+ } |
|
1005 |
+ } |
|
1006 |
+ } |
|
1007 |
+ return SzArEx_Fill(p, allocMain); |
|
1008 |
+} |
|
1009 |
+ |
|
1010 |
+static SRes SzReadHeader( |
|
1011 |
+ CSzArEx *p, |
|
1012 |
+ CSzData *sd, |
|
1013 |
+ ISzAlloc *allocMain, |
|
1014 |
+ ISzAlloc *allocTemp) |
|
1015 |
+{ |
|
1016 |
+ UInt64 *unpackSizes = 0; |
|
1017 |
+ Byte *digestsDefined = 0; |
|
1018 |
+ UInt32 *digests = 0; |
|
1019 |
+ Byte *emptyStreamVector = 0; |
|
1020 |
+ Byte *emptyFileVector = 0; |
|
1021 |
+ Byte *lwtVector = 0; |
|
1022 |
+ SRes res = SzReadHeader2(p, sd, |
|
1023 |
+ &unpackSizes, &digestsDefined, &digests, |
|
1024 |
+ &emptyStreamVector, &emptyFileVector, &lwtVector, |
|
1025 |
+ allocMain, allocTemp); |
|
1026 |
+ IAlloc_Free(allocTemp, unpackSizes); |
|
1027 |
+ IAlloc_Free(allocTemp, digestsDefined); |
|
1028 |
+ IAlloc_Free(allocTemp, digests); |
|
1029 |
+ IAlloc_Free(allocTemp, emptyStreamVector); |
|
1030 |
+ IAlloc_Free(allocTemp, emptyFileVector); |
|
1031 |
+ IAlloc_Free(allocTemp, lwtVector); |
|
1032 |
+ return res; |
|
1033 |
+} |
|
1034 |
+ |
|
1035 |
+static SRes SzReadAndDecodePackedStreams2( |
|
1036 |
+ ILookInStream *inStream, |
|
1037 |
+ CSzData *sd, |
|
1038 |
+ CBuf *outBuffer, |
|
1039 |
+ UInt64 baseOffset, |
|
1040 |
+ CSzAr *p, |
|
1041 |
+ UInt64 **unpackSizes, |
|
1042 |
+ Byte **digestsDefined, |
|
1043 |
+ UInt32 **digests, |
|
1044 |
+ ISzAlloc *allocTemp) |
|
1045 |
+{ |
|
1046 |
+ |
|
1047 |
+ UInt32 numUnpackStreams = 0; |
|
1048 |
+ UInt64 dataStartPos; |
|
1049 |
+ CSzFolder *folder; |
|
1050 |
+ UInt64 unpackSize; |
|
1051 |
+ SRes res; |
|
1052 |
+ |
|
1053 |
+ RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, |
|
1054 |
+ &numUnpackStreams, unpackSizes, digestsDefined, digests, |
|
1055 |
+ allocTemp, allocTemp)); |
|
1056 |
+ |
|
1057 |
+ dataStartPos += baseOffset; |
|
1058 |
+ if (p->NumFolders != 1) |
|
1059 |
+ return SZ_ERROR_ARCHIVE; |
|
1060 |
+ |
|
1061 |
+ folder = p->Folders; |
|
1062 |
+ unpackSize = SzFolder_GetUnpackSize(folder); |
|
1063 |
+ |
|
1064 |
+ RINOK(LookInStream_SeekTo(inStream, dataStartPos)); |
|
1065 |
+ |
|
1066 |
+ if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) |
|
1067 |
+ return SZ_ERROR_MEM; |
|
1068 |
+ |
|
1069 |
+ res = SzDecode(p->PackSizes, folder, |
|
1070 |
+ inStream, dataStartPos, |
|
1071 |
+ outBuffer->data, (size_t)unpackSize, allocTemp); |
|
1072 |
+ RINOK(res); |
|
1073 |
+ if (folder->UnpackCRCDefined) |
|
1074 |
+ if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) |
|
1075 |
+ return SZ_ERROR_CRC; |
|
1076 |
+ return SZ_OK; |
|
1077 |
+} |
|
1078 |
+ |
|
1079 |
+static SRes SzReadAndDecodePackedStreams( |
|
1080 |
+ ILookInStream *inStream, |
|
1081 |
+ CSzData *sd, |
|
1082 |
+ CBuf *outBuffer, |
|
1083 |
+ UInt64 baseOffset, |
|
1084 |
+ ISzAlloc *allocTemp) |
|
1085 |
+{ |
|
1086 |
+ CSzAr p; |
|
1087 |
+ UInt64 *unpackSizes = 0; |
|
1088 |
+ Byte *digestsDefined = 0; |
|
1089 |
+ UInt32 *digests = 0; |
|
1090 |
+ SRes res; |
|
1091 |
+ SzAr_Init(&p); |
|
1092 |
+ res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, |
|
1093 |
+ &p, &unpackSizes, &digestsDefined, &digests, |
|
1094 |
+ allocTemp); |
|
1095 |
+ SzAr_Free(&p, allocTemp); |
|
1096 |
+ IAlloc_Free(allocTemp, unpackSizes); |
|
1097 |
+ IAlloc_Free(allocTemp, digestsDefined); |
|
1098 |
+ IAlloc_Free(allocTemp, digests); |
|
1099 |
+ return res; |
|
1100 |
+} |
|
1101 |
+ |
|
1102 |
+static SRes SzArEx_Open2( |
|
1103 |
+ CSzArEx *p, |
|
1104 |
+ ILookInStream *inStream, |
|
1105 |
+ ISzAlloc *allocMain, |
|
1106 |
+ ISzAlloc *allocTemp) |
|
1107 |
+{ |
|
1108 |
+ Byte header[k7zStartHeaderSize]; |
|
1109 |
+ UInt64 nextHeaderOffset, nextHeaderSize; |
|
1110 |
+ size_t nextHeaderSizeT; |
|
1111 |
+ UInt32 nextHeaderCRC; |
|
1112 |
+ CBuf buffer; |
|
1113 |
+ SRes res; |
|
1114 |
+ |
|
1115 |
+ RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); |
|
1116 |
+ |
|
1117 |
+ if (!TestSignatureCandidate(header)) |
|
1118 |
+ return SZ_ERROR_NO_ARCHIVE; |
|
1119 |
+ if (header[6] != k7zMajorVersion) |
|
1120 |
+ return SZ_ERROR_UNSUPPORTED; |
|
1121 |
+ |
|
1122 |
+ nextHeaderOffset = GetUi64(header + 12); |
|
1123 |
+ nextHeaderSize = GetUi64(header + 20); |
|
1124 |
+ nextHeaderCRC = GetUi32(header + 28); |
|
1125 |
+ |
|
1126 |
+ p->startPosAfterHeader = k7zStartHeaderSize; |
|
1127 |
+ |
|
1128 |
+ if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) |
|
1129 |
+ return SZ_ERROR_CRC; |
|
1130 |
+ |
|
1131 |
+ nextHeaderSizeT = (size_t)nextHeaderSize; |
|
1132 |
+ if (nextHeaderSizeT != nextHeaderSize) |
|
1133 |
+ return SZ_ERROR_MEM; |
|
1134 |
+ if (nextHeaderSizeT == 0) |
|
1135 |
+ return SZ_OK; |
|
1136 |
+ if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || |
|
1137 |
+ nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) |
|
1138 |
+ return SZ_ERROR_NO_ARCHIVE; |
|
1139 |
+ |
|
1140 |
+ { |
|
1141 |
+ Int64 pos = 0; |
|
1142 |
+ RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); |
|
1143 |
+ if ((UInt64)pos < nextHeaderOffset || |
|
1144 |
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || |
|
1145 |
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) |
|
1146 |
+ return SZ_ERROR_INPUT_EOF; |
|
1147 |
+ } |
|
1148 |
+ |
|
1149 |
+ RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); |
|
1150 |
+ |
|
1151 |
+ if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) |
|
1152 |
+ return SZ_ERROR_MEM; |
|
1153 |
+ |
|
1154 |
+ res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); |
|
1155 |
+ if (res == SZ_OK) |
|
1156 |
+ { |
|
1157 |
+ res = SZ_ERROR_ARCHIVE; |
|
1158 |
+ if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) |
|
1159 |
+ { |
|
1160 |
+ CSzData sd; |
|
1161 |
+ UInt64 type; |
|
1162 |
+ sd.Data = buffer.data; |
|
1163 |
+ sd.Size = buffer.size; |
|
1164 |
+ res = SzReadID(&sd, &type); |
|
1165 |
+ if (res == SZ_OK) |
|
1166 |
+ { |
|
1167 |
+ if (type == k7zIdEncodedHeader) |
|
1168 |
+ { |
|
1169 |
+ CBuf outBuffer; |
|
1170 |
+ Buf_Init(&outBuffer); |
|
1171 |
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); |
|
1172 |
+ if (res != SZ_OK) |
|
1173 |
+ Buf_Free(&outBuffer, allocTemp); |
|
1174 |
+ else |
|
1175 |
+ { |
|
1176 |
+ Buf_Free(&buffer, allocTemp); |
|
1177 |
+ buffer.data = outBuffer.data; |
|
1178 |
+ buffer.size = outBuffer.size; |
|
1179 |
+ sd.Data = buffer.data; |
|
1180 |
+ sd.Size = buffer.size; |
|
1181 |
+ res = SzReadID(&sd, &type); |
|
1182 |
+ } |
|
1183 |
+ } |
|
1184 |
+ } |
|
1185 |
+ if (res == SZ_OK) |
|
1186 |
+ { |
|
1187 |
+ if (type == k7zIdHeader) |
|
1188 |
+ res = SzReadHeader(p, &sd, allocMain, allocTemp); |
|
1189 |
+ else |
|
1190 |
+ res = SZ_ERROR_UNSUPPORTED; |
|
1191 |
+ } |
|
1192 |
+ } |
|
1193 |
+ } |
|
1194 |
+ Buf_Free(&buffer, allocTemp); |
|
1195 |
+ return res; |
|
1196 |
+} |
|
1197 |
+ |
|
1198 |
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) |
|
1199 |
+{ |
|
1200 |
+ SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); |
|
1201 |
+ if (res != SZ_OK) |
|
1202 |
+ SzArEx_Free(p, allocMain); |
|
1203 |
+ return res; |
|
1204 |
+} |
... | ... |
@@ -1,41 +1,41 @@ |
1 |
-/* 7zIn.h -- 7z Input functions |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_IN_H |
|
5 |
-#define __7Z_IN_H |
|
6 |
- |
|
7 |
-#include "7zHeader.h" |
|
8 |
-#include "7zItem.h" |
|
9 |
- |
|
10 |
-typedef struct |
|
11 |
-{ |
|
12 |
- CSzAr db; |
|
13 |
- |
|
14 |
- UInt64 startPosAfterHeader; |
|
15 |
- UInt64 dataPos; |
|
16 |
- |
|
17 |
- UInt32 *FolderStartPackStreamIndex; |
|
18 |
- UInt64 *PackStreamStartPositions; |
|
19 |
- UInt32 *FolderStartFileIndex; |
|
20 |
- UInt32 *FileIndexToFolderIndexMap; |
|
21 |
-} CSzArEx; |
|
22 |
- |
|
23 |
-void SzArEx_Init(CSzArEx *p); |
|
24 |
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); |
|
25 |
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); |
|
26 |
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); |
|
27 |
- |
|
28 |
-/* |
|
29 |
-Errors: |
|
30 |
-SZ_ERROR_NO_ARCHIVE |
|
31 |
-SZ_ERROR_ARCHIVE |
|
32 |
-SZ_ERROR_UNSUPPORTED |
|
33 |
-SZ_ERROR_MEM |
|
34 |
-SZ_ERROR_CRC |
|
35 |
-SZ_ERROR_INPUT_EOF |
|
36 |
-SZ_ERROR_FAIL |
|
37 |
-*/ |
|
38 |
- |
|
39 |
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); |
|
40 |
- |
|
41 |
-#endif |
|
1 |
+/* 7zIn.h -- 7z Input functions |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_IN_H |
|
5 |
+#define __7Z_IN_H |
|
6 |
+ |
|
7 |
+#include "7zHeader.h" |
|
8 |
+#include "7zItem.h" |
|
9 |
+ |
|
10 |
+typedef struct |
|
11 |
+{ |
|
12 |
+ CSzAr db; |
|
13 |
+ |
|
14 |
+ UInt64 startPosAfterHeader; |
|
15 |
+ UInt64 dataPos; |
|
16 |
+ |
|
17 |
+ UInt32 *FolderStartPackStreamIndex; |
|
18 |
+ UInt64 *PackStreamStartPositions; |
|
19 |
+ UInt32 *FolderStartFileIndex; |
|
20 |
+ UInt32 *FileIndexToFolderIndexMap; |
|
21 |
+} CSzArEx; |
|
22 |
+ |
|
23 |
+void SzArEx_Init(CSzArEx *p); |
|
24 |
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); |
|
25 |
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); |
|
26 |
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); |
|
27 |
+ |
|
28 |
+/* |
|
29 |
+Errors: |
|
30 |
+SZ_ERROR_NO_ARCHIVE |
|
31 |
+SZ_ERROR_ARCHIVE |
|
32 |
+SZ_ERROR_UNSUPPORTED |
|
33 |
+SZ_ERROR_MEM |
|
34 |
+SZ_ERROR_CRC |
|
35 |
+SZ_ERROR_INPUT_EOF |
|
36 |
+SZ_ERROR_FAIL |
|
37 |
+*/ |
|
38 |
+ |
|
39 |
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); |
|
40 |
+ |
|
41 |
+#endif |
... | ... |
@@ -1,127 +1,127 @@ |
1 |
-/* 7zItem.c -- 7z Items |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "7zItem.h" |
|
5 |
- |
|
6 |
-void SzCoderInfo_Init(CSzCoderInfo *p) |
|
7 |
-{ |
|
8 |
- Buf_Init(&p->Props); |
|
9 |
-} |
|
10 |
- |
|
11 |
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) |
|
12 |
-{ |
|
13 |
- Buf_Free(&p->Props, alloc); |
|
14 |
- SzCoderInfo_Init(p); |
|
15 |
-} |
|
16 |
- |
|
17 |
-void SzFolder_Init(CSzFolder *p) |
|
18 |
-{ |
|
19 |
- p->Coders = 0; |
|
20 |
- p->BindPairs = 0; |
|
21 |
- p->PackStreams = 0; |
|
22 |
- p->UnpackSizes = 0; |
|
23 |
- p->NumCoders = 0; |
|
24 |
- p->NumBindPairs = 0; |
|
25 |
- p->NumPackStreams = 0; |
|
26 |
- p->UnpackCRCDefined = 0; |
|
27 |
- p->UnpackCRC = 0; |
|
28 |
- p->NumUnpackStreams = 0; |
|
29 |
-} |
|
30 |
- |
|
31 |
-void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) |
|
32 |
-{ |
|
33 |
- UInt32 i; |
|
34 |
- if (p->Coders) |
|
35 |
- for (i = 0; i < p->NumCoders; i++) |
|
36 |
- SzCoderInfo_Free(&p->Coders[i], alloc); |
|
37 |
- IAlloc_Free(alloc, p->Coders); |
|
38 |
- IAlloc_Free(alloc, p->BindPairs); |
|
39 |
- IAlloc_Free(alloc, p->PackStreams); |
|
40 |
- IAlloc_Free(alloc, p->UnpackSizes); |
|
41 |
- SzFolder_Init(p); |
|
42 |
-} |
|
43 |
- |
|
44 |
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) |
|
45 |
-{ |
|
46 |
- UInt32 result = 0; |
|
47 |
- UInt32 i; |
|
48 |
- for (i = 0; i < p->NumCoders; i++) |
|
49 |
- result += p->Coders[i].NumOutStreams; |
|
50 |
- return result; |
|
51 |
-} |
|
52 |
- |
|
53 |
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) |
|
54 |
-{ |
|
55 |
- UInt32 i; |
|
56 |
- for (i = 0; i < p->NumBindPairs; i++) |
|
57 |
- if (p->BindPairs[i].InIndex == inStreamIndex) |
|
58 |
- return i; |
|
59 |
- return -1; |
|
60 |
-} |
|
61 |
- |
|
62 |
- |
|
63 |
-int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) |
|
64 |
-{ |
|
65 |
- UInt32 i; |
|
66 |
- for (i = 0; i < p->NumBindPairs; i++) |
|
67 |
- if (p->BindPairs[i].OutIndex == outStreamIndex) |
|
68 |
- return i; |
|
69 |
- return -1; |
|
70 |
-} |
|
71 |
- |
|
72 |
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p) |
|
73 |
-{ |
|
74 |
- int i = (int)SzFolder_GetNumOutStreams(p); |
|
75 |
- if (i == 0) |
|
76 |
- return 0; |
|
77 |
- for (i--; i >= 0; i--) |
|
78 |
- if (SzFolder_FindBindPairForOutStream(p, i) < 0) |
|
79 |
- return p->UnpackSizes[i]; |
|
80 |
- /* throw 1; */ |
|
81 |
- return 0; |
|
82 |
-} |
|
83 |
- |
|
84 |
-void SzFile_Init(CSzFileItem *p) |
|
85 |
-{ |
|
86 |
- p->HasStream = 1; |
|
87 |
- p->IsDir = 0; |
|
88 |
- p->IsAnti = 0; |
|
89 |
- p->FileCRCDefined = 0; |
|
90 |
- p->MTimeDefined = 0; |
|
91 |
- p->Name = 0; |
|
92 |
-} |
|
93 |
- |
|
94 |
-static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) |
|
95 |
-{ |
|
96 |
- IAlloc_Free(alloc, p->Name); |
|
97 |
- SzFile_Init(p); |
|
98 |
-} |
|
99 |
- |
|
100 |
-void SzAr_Init(CSzAr *p) |
|
101 |
-{ |
|
102 |
- p->PackSizes = 0; |
|
103 |
- p->PackCRCsDefined = 0; |
|
104 |
- p->PackCRCs = 0; |
|
105 |
- p->Folders = 0; |
|
106 |
- p->Files = 0; |
|
107 |
- p->NumPackStreams = 0; |
|
108 |
- p->NumFolders = 0; |
|
109 |
- p->NumFiles = 0; |
|
110 |
-} |
|
111 |
- |
|
112 |
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc) |
|
113 |
-{ |
|
114 |
- UInt32 i; |
|
115 |
- if (p->Folders) |
|
116 |
- for (i = 0; i < p->NumFolders; i++) |
|
117 |
- SzFolder_Free(&p->Folders[i], alloc); |
|
118 |
- if (p->Files) |
|
119 |
- for (i = 0; i < p->NumFiles; i++) |
|
120 |
- SzFile_Free(&p->Files[i], alloc); |
|
121 |
- IAlloc_Free(alloc, p->PackSizes); |
|
122 |
- IAlloc_Free(alloc, p->PackCRCsDefined); |
|
123 |
- IAlloc_Free(alloc, p->PackCRCs); |
|
124 |
- IAlloc_Free(alloc, p->Folders); |
|
125 |
- IAlloc_Free(alloc, p->Files); |
|
126 |
- SzAr_Init(p); |
|
127 |
-} |
|
1 |
+/* 7zItem.c -- 7z Items |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "7zItem.h" |
|
5 |
+ |
|
6 |
+void SzCoderInfo_Init(CSzCoderInfo *p) |
|
7 |
+{ |
|
8 |
+ Buf_Init(&p->Props); |
|
9 |
+} |
|
10 |
+ |
|
11 |
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) |
|
12 |
+{ |
|
13 |
+ Buf_Free(&p->Props, alloc); |
|
14 |
+ SzCoderInfo_Init(p); |
|
15 |
+} |
|
16 |
+ |
|
17 |
+void SzFolder_Init(CSzFolder *p) |
|
18 |
+{ |
|
19 |
+ p->Coders = 0; |
|
20 |
+ p->BindPairs = 0; |
|
21 |
+ p->PackStreams = 0; |
|
22 |
+ p->UnpackSizes = 0; |
|
23 |
+ p->NumCoders = 0; |
|
24 |
+ p->NumBindPairs = 0; |
|
25 |
+ p->NumPackStreams = 0; |
|
26 |
+ p->UnpackCRCDefined = 0; |
|
27 |
+ p->UnpackCRC = 0; |
|
28 |
+ p->NumUnpackStreams = 0; |
|
29 |
+} |
|
30 |
+ |
|
31 |
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) |
|
32 |
+{ |
|
33 |
+ UInt32 i; |
|
34 |
+ if (p->Coders) |
|
35 |
+ for (i = 0; i < p->NumCoders; i++) |
|
36 |
+ SzCoderInfo_Free(&p->Coders[i], alloc); |
|
37 |
+ IAlloc_Free(alloc, p->Coders); |
|
38 |
+ IAlloc_Free(alloc, p->BindPairs); |
|
39 |
+ IAlloc_Free(alloc, p->PackStreams); |
|
40 |
+ IAlloc_Free(alloc, p->UnpackSizes); |
|
41 |
+ SzFolder_Init(p); |
|
42 |
+} |
|
43 |
+ |
|
44 |
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) |
|
45 |
+{ |
|
46 |
+ UInt32 result = 0; |
|
47 |
+ UInt32 i; |
|
48 |
+ for (i = 0; i < p->NumCoders; i++) |
|
49 |
+ result += p->Coders[i].NumOutStreams; |
|
50 |
+ return result; |
|
51 |
+} |
|
52 |
+ |
|
53 |
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) |
|
54 |
+{ |
|
55 |
+ UInt32 i; |
|
56 |
+ for (i = 0; i < p->NumBindPairs; i++) |
|
57 |
+ if (p->BindPairs[i].InIndex == inStreamIndex) |
|
58 |
+ return i; |
|
59 |
+ return -1; |
|
60 |
+} |
|
61 |
+ |
|
62 |
+ |
|
63 |
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) |
|
64 |
+{ |
|
65 |
+ UInt32 i; |
|
66 |
+ for (i = 0; i < p->NumBindPairs; i++) |
|
67 |
+ if (p->BindPairs[i].OutIndex == outStreamIndex) |
|
68 |
+ return i; |
|
69 |
+ return -1; |
|
70 |
+} |
|
71 |
+ |
|
72 |
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p) |
|
73 |
+{ |
|
74 |
+ int i = (int)SzFolder_GetNumOutStreams(p); |
|
75 |
+ if (i == 0) |
|
76 |
+ return 0; |
|
77 |
+ for (i--; i >= 0; i--) |
|
78 |
+ if (SzFolder_FindBindPairForOutStream(p, i) < 0) |
|
79 |
+ return p->UnpackSizes[i]; |
|
80 |
+ /* throw 1; */ |
|
81 |
+ return 0; |
|
82 |
+} |
|
83 |
+ |
|
84 |
+void SzFile_Init(CSzFileItem *p) |
|
85 |
+{ |
|
86 |
+ p->HasStream = 1; |
|
87 |
+ p->IsDir = 0; |
|
88 |
+ p->IsAnti = 0; |
|
89 |
+ p->FileCRCDefined = 0; |
|
90 |
+ p->MTimeDefined = 0; |
|
91 |
+ p->Name = 0; |
|
92 |
+} |
|
93 |
+ |
|
94 |
+static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) |
|
95 |
+{ |
|
96 |
+ IAlloc_Free(alloc, p->Name); |
|
97 |
+ SzFile_Init(p); |
|
98 |
+} |
|
99 |
+ |
|
100 |
+void SzAr_Init(CSzAr *p) |
|
101 |
+{ |
|
102 |
+ p->PackSizes = 0; |
|
103 |
+ p->PackCRCsDefined = 0; |
|
104 |
+ p->PackCRCs = 0; |
|
105 |
+ p->Folders = 0; |
|
106 |
+ p->Files = 0; |
|
107 |
+ p->NumPackStreams = 0; |
|
108 |
+ p->NumFolders = 0; |
|
109 |
+ p->NumFiles = 0; |
|
110 |
+} |
|
111 |
+ |
|
112 |
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc) |
|
113 |
+{ |
|
114 |
+ UInt32 i; |
|
115 |
+ if (p->Folders) |
|
116 |
+ for (i = 0; i < p->NumFolders; i++) |
|
117 |
+ SzFolder_Free(&p->Folders[i], alloc); |
|
118 |
+ if (p->Files) |
|
119 |
+ for (i = 0; i < p->NumFiles; i++) |
|
120 |
+ SzFile_Free(&p->Files[i], alloc); |
|
121 |
+ IAlloc_Free(alloc, p->PackSizes); |
|
122 |
+ IAlloc_Free(alloc, p->PackCRCsDefined); |
|
123 |
+ IAlloc_Free(alloc, p->PackCRCs); |
|
124 |
+ IAlloc_Free(alloc, p->Folders); |
|
125 |
+ IAlloc_Free(alloc, p->Files); |
|
126 |
+ SzAr_Init(p); |
|
127 |
+} |
... | ... |
@@ -1,84 +1,84 @@ |
1 |
-/* 7zItem.h -- 7z Items |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_ITEM_H |
|
5 |
-#define __7Z_ITEM_H |
|
6 |
- |
|
7 |
-#include "../../7zBuf.h" |
|
8 |
- |
|
9 |
-typedef struct |
|
10 |
-{ |
|
11 |
- UInt32 NumInStreams; |
|
12 |
- UInt32 NumOutStreams; |
|
13 |
- UInt64 MethodID; |
|
14 |
- CBuf Props; |
|
15 |
-} CSzCoderInfo; |
|
16 |
- |
|
17 |
-void SzCoderInfo_Init(CSzCoderInfo *p); |
|
18 |
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); |
|
19 |
- |
|
20 |
-typedef struct |
|
21 |
-{ |
|
22 |
- UInt32 InIndex; |
|
23 |
- UInt32 OutIndex; |
|
24 |
-} CBindPair; |
|
25 |
- |
|
26 |
-typedef struct |
|
27 |
-{ |
|
28 |
- CSzCoderInfo *Coders; |
|
29 |
- CBindPair *BindPairs; |
|
30 |
- UInt32 *PackStreams; |
|
31 |
- UInt64 *UnpackSizes; |
|
32 |
- UInt32 NumCoders; |
|
33 |
- UInt32 NumBindPairs; |
|
34 |
- UInt32 NumPackStreams; |
|
35 |
- int UnpackCRCDefined; |
|
36 |
- UInt32 UnpackCRC; |
|
37 |
- |
|
38 |
- UInt32 NumUnpackStreams; |
|
39 |
-} CSzFolder; |
|
40 |
- |
|
41 |
-void SzFolder_Init(CSzFolder *p); |
|
42 |
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
43 |
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); |
|
44 |
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); |
|
45 |
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
46 |
- |
|
47 |
-typedef struct |
|
48 |
-{ |
|
49 |
- UInt32 Low; |
|
50 |
- UInt32 High; |
|
51 |
-} CNtfsFileTime; |
|
52 |
- |
|
53 |
-typedef struct |
|
54 |
-{ |
|
55 |
- CNtfsFileTime MTime; |
|
56 |
- UInt64 Size; |
|
57 |
- char *Name; |
|
58 |
- UInt32 FileCRC; |
|
59 |
- |
|
60 |
- Byte HasStream; |
|
61 |
- Byte IsDir; |
|
62 |
- Byte IsAnti; |
|
63 |
- Byte FileCRCDefined; |
|
64 |
- Byte MTimeDefined; |
|
65 |
-} CSzFileItem; |
|
66 |
- |
|
67 |
-void SzFile_Init(CSzFileItem *p); |
|
68 |
- |
|
69 |
-typedef struct |
|
70 |
-{ |
|
71 |
- UInt64 *PackSizes; |
|
72 |
- Byte *PackCRCsDefined; |
|
73 |
- UInt32 *PackCRCs; |
|
74 |
- CSzFolder *Folders; |
|
75 |
- CSzFileItem *Files; |
|
76 |
- UInt32 NumPackStreams; |
|
77 |
- UInt32 NumFolders; |
|
78 |
- UInt32 NumFiles; |
|
79 |
-} CSzAr; |
|
80 |
- |
|
81 |
-void SzAr_Init(CSzAr *p); |
|
82 |
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc); |
|
83 |
- |
|
84 |
-#endif |
|
1 |
+/* 7zItem.h -- 7z Items |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_ITEM_H |
|
5 |
+#define __7Z_ITEM_H |
|
6 |
+ |
|
7 |
+#include "../../7zBuf.h" |
|
8 |
+ |
|
9 |
+typedef struct |
|
10 |
+{ |
|
11 |
+ UInt32 NumInStreams; |
|
12 |
+ UInt32 NumOutStreams; |
|
13 |
+ UInt64 MethodID; |
|
14 |
+ CBuf Props; |
|
15 |
+} CSzCoderInfo; |
|
16 |
+ |
|
17 |
+void SzCoderInfo_Init(CSzCoderInfo *p); |
|
18 |
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); |
|
19 |
+ |
|
20 |
+typedef struct |
|
21 |
+{ |
|
22 |
+ UInt32 InIndex; |
|
23 |
+ UInt32 OutIndex; |
|
24 |
+} CBindPair; |
|
25 |
+ |
|
26 |
+typedef struct |
|
27 |
+{ |
|
28 |
+ CSzCoderInfo *Coders; |
|
29 |
+ CBindPair *BindPairs; |
|
30 |
+ UInt32 *PackStreams; |
|
31 |
+ UInt64 *UnpackSizes; |
|
32 |
+ UInt32 NumCoders; |
|
33 |
+ UInt32 NumBindPairs; |
|
34 |
+ UInt32 NumPackStreams; |
|
35 |
+ int UnpackCRCDefined; |
|
36 |
+ UInt32 UnpackCRC; |
|
37 |
+ |
|
38 |
+ UInt32 NumUnpackStreams; |
|
39 |
+} CSzFolder; |
|
40 |
+ |
|
41 |
+void SzFolder_Init(CSzFolder *p); |
|
42 |
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
43 |
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); |
|
44 |
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); |
|
45 |
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
46 |
+ |
|
47 |
+typedef struct |
|
48 |
+{ |
|
49 |
+ UInt32 Low; |
|
50 |
+ UInt32 High; |
|
51 |
+} CNtfsFileTime; |
|
52 |
+ |
|
53 |
+typedef struct |
|
54 |
+{ |
|
55 |
+ CNtfsFileTime MTime; |
|
56 |
+ UInt64 Size; |
|
57 |
+ char *Name; |
|
58 |
+ UInt32 FileCRC; |
|
59 |
+ |
|
60 |
+ Byte HasStream; |
|
61 |
+ Byte IsDir; |
|
62 |
+ Byte IsAnti; |
|
63 |
+ Byte FileCRCDefined; |
|
64 |
+ Byte MTimeDefined; |
|
65 |
+} CSzFileItem; |
|
66 |
+ |
|
67 |
+void SzFile_Init(CSzFileItem *p); |
|
68 |
+ |
|
69 |
+typedef struct |
|
70 |
+{ |
|
71 |
+ UInt64 *PackSizes; |
|
72 |
+ Byte *PackCRCsDefined; |
|
73 |
+ UInt32 *PackCRCs; |
|
74 |
+ CSzFolder *Folders; |
|
75 |
+ CSzFileItem *Files; |
|
76 |
+ UInt32 NumPackStreams; |
|
77 |
+ UInt32 NumFolders; |
|
78 |
+ UInt32 NumFiles; |
|
79 |
+} CSzAr; |
|
80 |
+ |
|
81 |
+void SzAr_Init(CSzAr *p); |
|
82 |
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc); |
|
83 |
+ |
|
84 |
+#endif |
... | ... |
@@ -1,132 +1,132 @@ |
1 |
-/* Bcj2.c -- Converter for x86 code (BCJ2) |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bcj2.h" |
|
5 |
- |
|
6 |
-#ifdef _LZMA_PROB32 |
|
7 |
-#define CProb UInt32 |
|
8 |
-#else |
|
9 |
-#define CProb UInt16 |
|
10 |
-#endif |
|
11 |
- |
|
12 |
-#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) |
|
13 |
-#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) |
|
14 |
- |
|
15 |
-#define kNumTopBits 24 |
|
16 |
-#define kTopValue ((UInt32)1 << kNumTopBits) |
|
17 |
- |
|
18 |
-#define kNumBitModelTotalBits 11 |
|
19 |
-#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
20 |
-#define kNumMoveBits 5 |
|
21 |
- |
|
22 |
-#define RC_READ_BYTE (*buffer++) |
|
23 |
-#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } |
|
24 |
-#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ |
|
25 |
- { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} |
|
26 |
- |
|
27 |
-#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } |
|
28 |
- |
|
29 |
-#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
30 |
-#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; |
|
31 |
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; |
|
32 |
- |
|
33 |
-int Bcj2_Decode( |
|
34 |
- const Byte *buf0, SizeT size0, |
|
35 |
- const Byte *buf1, SizeT size1, |
|
36 |
- const Byte *buf2, SizeT size2, |
|
37 |
- const Byte *buf3, SizeT size3, |
|
38 |
- Byte *outBuf, SizeT outSize) |
|
39 |
-{ |
|
40 |
- CProb p[256 + 2]; |
|
41 |
- SizeT inPos = 0, outPos = 0; |
|
42 |
- |
|
43 |
- const Byte *buffer, *bufferLim; |
|
44 |
- UInt32 range, code; |
|
45 |
- Byte prevByte = 0; |
|
46 |
- |
|
47 |
- unsigned int i; |
|
48 |
- for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) |
|
49 |
- p[i] = kBitModelTotal >> 1; |
|
50 |
- |
|
51 |
- buffer = buf3; |
|
52 |
- bufferLim = buffer + size3; |
|
53 |
- RC_INIT2 |
|
54 |
- |
|
55 |
- if (outSize == 0) |
|
56 |
- return SZ_OK; |
|
57 |
- |
|
58 |
- for (;;) |
|
59 |
- { |
|
60 |
- Byte b; |
|
61 |
- CProb *prob; |
|
62 |
- UInt32 bound; |
|
63 |
- UInt32 ttt; |
|
64 |
- |
|
65 |
- SizeT limit = size0 - inPos; |
|
66 |
- if (outSize - outPos < limit) |
|
67 |
- limit = outSize - outPos; |
|
68 |
- while (limit != 0) |
|
69 |
- { |
|
70 |
- Byte b = buf0[inPos]; |
|
71 |
- outBuf[outPos++] = b; |
|
72 |
- if (IsJ(prevByte, b)) |
|
73 |
- break; |
|
74 |
- inPos++; |
|
75 |
- prevByte = b; |
|
76 |
- limit--; |
|
77 |
- } |
|
78 |
- |
|
79 |
- if (limit == 0 || outPos == outSize) |
|
80 |
- break; |
|
81 |
- |
|
82 |
- b = buf0[inPos++]; |
|
83 |
- |
|
84 |
- if (b == 0xE8) |
|
85 |
- prob = p + prevByte; |
|
86 |
- else if (b == 0xE9) |
|
87 |
- prob = p + 256; |
|
88 |
- else |
|
89 |
- prob = p + 257; |
|
90 |
- |
|
91 |
- IF_BIT_0(prob) |
|
92 |
- { |
|
93 |
- UPDATE_0(prob) |
|
94 |
- prevByte = b; |
|
95 |
- } |
|
96 |
- else |
|
97 |
- { |
|
98 |
- UInt32 dest; |
|
99 |
- const Byte *v; |
|
100 |
- UPDATE_1(prob) |
|
101 |
- if (b == 0xE8) |
|
102 |
- { |
|
103 |
- v = buf1; |
|
104 |
- if (size1 < 4) |
|
105 |
- return SZ_ERROR_DATA; |
|
106 |
- buf1 += 4; |
|
107 |
- size1 -= 4; |
|
108 |
- } |
|
109 |
- else |
|
110 |
- { |
|
111 |
- v = buf2; |
|
112 |
- if (size2 < 4) |
|
113 |
- return SZ_ERROR_DATA; |
|
114 |
- buf2 += 4; |
|
115 |
- size2 -= 4; |
|
116 |
- } |
|
117 |
- dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | |
|
118 |
- ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); |
|
119 |
- outBuf[outPos++] = (Byte)dest; |
|
120 |
- if (outPos == outSize) |
|
121 |
- break; |
|
122 |
- outBuf[outPos++] = (Byte)(dest >> 8); |
|
123 |
- if (outPos == outSize) |
|
124 |
- break; |
|
125 |
- outBuf[outPos++] = (Byte)(dest >> 16); |
|
126 |
- if (outPos == outSize) |
|
127 |
- break; |
|
128 |
- outBuf[outPos++] = prevByte = (Byte)(dest >> 24); |
|
129 |
- } |
|
130 |
- } |
|
131 |
- return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; |
|
132 |
-} |
|
1 |
+/* Bcj2.c -- Converter for x86 code (BCJ2) |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bcj2.h" |
|
5 |
+ |
|
6 |
+#ifdef _LZMA_PROB32 |
|
7 |
+#define CProb UInt32 |
|
8 |
+#else |
|
9 |
+#define CProb UInt16 |
|
10 |
+#endif |
|
11 |
+ |
|
12 |
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) |
|
13 |
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) |
|
14 |
+ |
|
15 |
+#define kNumTopBits 24 |
|
16 |
+#define kTopValue ((UInt32)1 << kNumTopBits) |
|
17 |
+ |
|
18 |
+#define kNumBitModelTotalBits 11 |
|
19 |
+#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
20 |
+#define kNumMoveBits 5 |
|
21 |
+ |
|
22 |
+#define RC_READ_BYTE (*buffer++) |
|
23 |
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } |
|
24 |
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ |
|
25 |
+ { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} |
|
26 |
+ |
|
27 |
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } |
|
28 |
+ |
|
29 |
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
30 |
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; |
|
31 |
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; |
|
32 |
+ |
|
33 |
+int Bcj2_Decode( |
|
34 |
+ const Byte *buf0, SizeT size0, |
|
35 |
+ const Byte *buf1, SizeT size1, |
|
36 |
+ const Byte *buf2, SizeT size2, |
|
37 |
+ const Byte *buf3, SizeT size3, |
|
38 |
+ Byte *outBuf, SizeT outSize) |
|
39 |
+{ |
|
40 |
+ CProb p[256 + 2]; |
|
41 |
+ SizeT inPos = 0, outPos = 0; |
|
42 |
+ |
|
43 |
+ const Byte *buffer, *bufferLim; |
|
44 |
+ UInt32 range, code; |
|
45 |
+ Byte prevByte = 0; |
|
46 |
+ |
|
47 |
+ unsigned int i; |
|
48 |
+ for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) |
|
49 |
+ p[i] = kBitModelTotal >> 1; |
|
50 |
+ |
|
51 |
+ buffer = buf3; |
|
52 |
+ bufferLim = buffer + size3; |
|
53 |
+ RC_INIT2 |
|
54 |
+ |
|
55 |
+ if (outSize == 0) |
|
56 |
+ return SZ_OK; |
|
57 |
+ |
|
58 |
+ for (;;) |
|
59 |
+ { |
|
60 |
+ Byte b; |
|
61 |
+ CProb *prob; |
|
62 |
+ UInt32 bound; |
|
63 |
+ UInt32 ttt; |
|
64 |
+ |
|
65 |
+ SizeT limit = size0 - inPos; |
|
66 |
+ if (outSize - outPos < limit) |
|
67 |
+ limit = outSize - outPos; |
|
68 |
+ while (limit != 0) |
|
69 |
+ { |
|
70 |
+ Byte b = buf0[inPos]; |
|
71 |
+ outBuf[outPos++] = b; |
|
72 |
+ if (IsJ(prevByte, b)) |
|
73 |
+ break; |
|
74 |
+ inPos++; |
|
75 |
+ prevByte = b; |
|
76 |
+ limit--; |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ if (limit == 0 || outPos == outSize) |
|
80 |
+ break; |
|
81 |
+ |
|
82 |
+ b = buf0[inPos++]; |
|
83 |
+ |
|
84 |
+ if (b == 0xE8) |
|
85 |
+ prob = p + prevByte; |
|
86 |
+ else if (b == 0xE9) |
|
87 |
+ prob = p + 256; |
|
88 |
+ else |
|
89 |
+ prob = p + 257; |
|
90 |
+ |
|
91 |
+ IF_BIT_0(prob) |
|
92 |
+ { |
|
93 |
+ UPDATE_0(prob) |
|
94 |
+ prevByte = b; |
|
95 |
+ } |
|
96 |
+ else |
|
97 |
+ { |
|
98 |
+ UInt32 dest; |
|
99 |
+ const Byte *v; |
|
100 |
+ UPDATE_1(prob) |
|
101 |
+ if (b == 0xE8) |
|
102 |
+ { |
|
103 |
+ v = buf1; |
|
104 |
+ if (size1 < 4) |
|
105 |
+ return SZ_ERROR_DATA; |
|
106 |
+ buf1 += 4; |
|
107 |
+ size1 -= 4; |
|
108 |
+ } |
|
109 |
+ else |
|
110 |
+ { |
|
111 |
+ v = buf2; |
|
112 |
+ if (size2 < 4) |
|
113 |
+ return SZ_ERROR_DATA; |
|
114 |
+ buf2 += 4; |
|
115 |
+ size2 -= 4; |
|
116 |
+ } |
|
117 |
+ dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | |
|
118 |
+ ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); |
|
119 |
+ outBuf[outPos++] = (Byte)dest; |
|
120 |
+ if (outPos == outSize) |
|
121 |
+ break; |
|
122 |
+ outBuf[outPos++] = (Byte)(dest >> 8); |
|
123 |
+ if (outPos == outSize) |
|
124 |
+ break; |
|
125 |
+ outBuf[outPos++] = (Byte)(dest >> 16); |
|
126 |
+ if (outPos == outSize) |
|
127 |
+ break; |
|
128 |
+ outBuf[outPos++] = prevByte = (Byte)(dest >> 24); |
|
129 |
+ } |
|
130 |
+ } |
|
131 |
+ return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; |
|
132 |
+} |
... | ... |
@@ -1,30 +1,30 @@ |
1 |
-/* Bcj2.h -- Converter for x86 code (BCJ2) |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __BCJ2_H |
|
5 |
-#define __BCJ2_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-/* |
|
10 |
-Conditions: |
|
11 |
- outSize <= FullOutputSize, |
|
12 |
- where FullOutputSize is full size of output stream of x86_2 filter. |
|
13 |
- |
|
14 |
-If buf0 overlaps outBuf, there are two required conditions: |
|
15 |
- 1) (buf0 >= outBuf) |
|
16 |
- 2) (buf0 + size0 >= outBuf + FullOutputSize). |
|
17 |
- |
|
18 |
-Returns: |
|
19 |
- SZ_OK |
|
20 |
- SZ_ERROR_DATA - Data error |
|
21 |
-*/ |
|
22 |
- |
|
23 |
-int Bcj2_Decode( |
|
24 |
- const Byte *buf0, SizeT size0, |
|
25 |
- const Byte *buf1, SizeT size1, |
|
26 |
- const Byte *buf2, SizeT size2, |
|
27 |
- const Byte *buf3, SizeT size3, |
|
28 |
- Byte *outBuf, SizeT outSize); |
|
29 |
- |
|
30 |
-#endif |
|
1 |
+/* Bcj2.h -- Converter for x86 code (BCJ2) |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __BCJ2_H |
|
5 |
+#define __BCJ2_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+/* |
|
10 |
+Conditions: |
|
11 |
+ outSize <= FullOutputSize, |
|
12 |
+ where FullOutputSize is full size of output stream of x86_2 filter. |
|
13 |
+ |
|
14 |
+If buf0 overlaps outBuf, there are two required conditions: |
|
15 |
+ 1) (buf0 >= outBuf) |
|
16 |
+ 2) (buf0 + size0 >= outBuf + FullOutputSize). |
|
17 |
+ |
|
18 |
+Returns: |
|
19 |
+ SZ_OK |
|
20 |
+ SZ_ERROR_DATA - Data error |
|
21 |
+*/ |
|
22 |
+ |
|
23 |
+int Bcj2_Decode( |
|
24 |
+ const Byte *buf0, SizeT size0, |
|
25 |
+ const Byte *buf1, SizeT size1, |
|
26 |
+ const Byte *buf2, SizeT size2, |
|
27 |
+ const Byte *buf3, SizeT size3, |
|
28 |
+ Byte *outBuf, SizeT outSize); |
|
29 |
+ |
|
30 |
+#endif |
... | ... |
@@ -1,133 +1,133 @@ |
1 |
-/* Bra.c -- Converters for RISC code |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bra.h" |
|
5 |
- |
|
6 |
-SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
7 |
-{ |
|
8 |
- SizeT i; |
|
9 |
- if (size < 4) |
|
10 |
- return 0; |
|
11 |
- size -= 4; |
|
12 |
- ip += 8; |
|
13 |
- for (i = 0; i <= size; i += 4) |
|
14 |
- { |
|
15 |
- if (data[i + 3] == 0xEB) |
|
16 |
- { |
|
17 |
- UInt32 dest; |
|
18 |
- UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); |
|
19 |
- src <<= 2; |
|
20 |
- if (encoding) |
|
21 |
- dest = ip + (UInt32)i + src; |
|
22 |
- else |
|
23 |
- dest = src - (ip + (UInt32)i); |
|
24 |
- dest >>= 2; |
|
25 |
- data[i + 2] = (Byte)(dest >> 16); |
|
26 |
- data[i + 1] = (Byte)(dest >> 8); |
|
27 |
- data[i + 0] = (Byte)dest; |
|
28 |
- } |
|
29 |
- } |
|
30 |
- return i; |
|
31 |
-} |
|
32 |
- |
|
33 |
-SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
34 |
-{ |
|
35 |
- SizeT i; |
|
36 |
- if (size < 4) |
|
37 |
- return 0; |
|
38 |
- size -= 4; |
|
39 |
- ip += 4; |
|
40 |
- for (i = 0; i <= size; i += 2) |
|
41 |
- { |
|
42 |
- if ((data[i + 1] & 0xF8) == 0xF0 && |
|
43 |
- (data[i + 3] & 0xF8) == 0xF8) |
|
44 |
- { |
|
45 |
- UInt32 dest; |
|
46 |
- UInt32 src = |
|
47 |
- (((UInt32)data[i + 1] & 0x7) << 19) | |
|
48 |
- ((UInt32)data[i + 0] << 11) | |
|
49 |
- (((UInt32)data[i + 3] & 0x7) << 8) | |
|
50 |
- (data[i + 2]); |
|
51 |
- |
|
52 |
- src <<= 1; |
|
53 |
- if (encoding) |
|
54 |
- dest = ip + (UInt32)i + src; |
|
55 |
- else |
|
56 |
- dest = src - (ip + (UInt32)i); |
|
57 |
- dest >>= 1; |
|
58 |
- |
|
59 |
- data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); |
|
60 |
- data[i + 0] = (Byte)(dest >> 11); |
|
61 |
- data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); |
|
62 |
- data[i + 2] = (Byte)dest; |
|
63 |
- i += 2; |
|
64 |
- } |
|
65 |
- } |
|
66 |
- return i; |
|
67 |
-} |
|
68 |
- |
|
69 |
-SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
70 |
-{ |
|
71 |
- SizeT i; |
|
72 |
- if (size < 4) |
|
73 |
- return 0; |
|
74 |
- size -= 4; |
|
75 |
- for (i = 0; i <= size; i += 4) |
|
76 |
- { |
|
77 |
- if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) |
|
78 |
- { |
|
79 |
- UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | |
|
80 |
- ((UInt32)data[i + 1] << 16) | |
|
81 |
- ((UInt32)data[i + 2] << 8) | |
|
82 |
- ((UInt32)data[i + 3] & (~3)); |
|
83 |
- |
|
84 |
- UInt32 dest; |
|
85 |
- if (encoding) |
|
86 |
- dest = ip + (UInt32)i + src; |
|
87 |
- else |
|
88 |
- dest = src - (ip + (UInt32)i); |
|
89 |
- data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); |
|
90 |
- data[i + 1] = (Byte)(dest >> 16); |
|
91 |
- data[i + 2] = (Byte)(dest >> 8); |
|
92 |
- data[i + 3] &= 0x3; |
|
93 |
- data[i + 3] |= dest; |
|
94 |
- } |
|
95 |
- } |
|
96 |
- return i; |
|
97 |
-} |
|
98 |
- |
|
99 |
-SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
100 |
-{ |
|
101 |
- UInt32 i; |
|
102 |
- if (size < 4) |
|
103 |
- return 0; |
|
104 |
- size -= 4; |
|
105 |
- for (i = 0; i <= size; i += 4) |
|
106 |
- { |
|
1 |
+/* Bra.c -- Converters for RISC code |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bra.h" |
|
5 |
+ |
|
6 |
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
7 |
+{ |
|
8 |
+ SizeT i; |
|
9 |
+ if (size < 4) |
|
10 |
+ return 0; |
|
11 |
+ size -= 4; |
|
12 |
+ ip += 8; |
|
13 |
+ for (i = 0; i <= size; i += 4) |
|
14 |
+ { |
|
15 |
+ if (data[i + 3] == 0xEB) |
|
16 |
+ { |
|
17 |
+ UInt32 dest; |
|
18 |
+ UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); |
|
19 |
+ src <<= 2; |
|
20 |
+ if (encoding) |
|
21 |
+ dest = ip + (UInt32)i + src; |
|
22 |
+ else |
|
23 |
+ dest = src - (ip + (UInt32)i); |
|
24 |
+ dest >>= 2; |
|
25 |
+ data[i + 2] = (Byte)(dest >> 16); |
|
26 |
+ data[i + 1] = (Byte)(dest >> 8); |
|
27 |
+ data[i + 0] = (Byte)dest; |
|
28 |
+ } |
|
29 |
+ } |
|
30 |
+ return i; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
34 |
+{ |
|
35 |
+ SizeT i; |
|
36 |
+ if (size < 4) |
|
37 |
+ return 0; |
|
38 |
+ size -= 4; |
|
39 |
+ ip += 4; |
|
40 |
+ for (i = 0; i <= size; i += 2) |
|
41 |
+ { |
|
42 |
+ if ((data[i + 1] & 0xF8) == 0xF0 && |
|
43 |
+ (data[i + 3] & 0xF8) == 0xF8) |
|
44 |
+ { |
|
45 |
+ UInt32 dest; |
|
46 |
+ UInt32 src = |
|
47 |
+ (((UInt32)data[i + 1] & 0x7) << 19) | |
|
48 |
+ ((UInt32)data[i + 0] << 11) | |
|
49 |
+ (((UInt32)data[i + 3] & 0x7) << 8) | |
|
50 |
+ (data[i + 2]); |
|
51 |
+ |
|
52 |
+ src <<= 1; |
|
53 |
+ if (encoding) |
|
54 |
+ dest = ip + (UInt32)i + src; |
|
55 |
+ else |
|
56 |
+ dest = src - (ip + (UInt32)i); |
|
57 |
+ dest >>= 1; |
|
58 |
+ |
|
59 |
+ data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); |
|
60 |
+ data[i + 0] = (Byte)(dest >> 11); |
|
61 |
+ data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); |
|
62 |
+ data[i + 2] = (Byte)dest; |
|
63 |
+ i += 2; |
|
64 |
+ } |
|
65 |
+ } |
|
66 |
+ return i; |
|
67 |
+} |
|
68 |
+ |
|
69 |
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
70 |
+{ |
|
71 |
+ SizeT i; |
|
72 |
+ if (size < 4) |
|
73 |
+ return 0; |
|
74 |
+ size -= 4; |
|
75 |
+ for (i = 0; i <= size; i += 4) |
|
76 |
+ { |
|
77 |
+ if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) |
|
78 |
+ { |
|
79 |
+ UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | |
|
80 |
+ ((UInt32)data[i + 1] << 16) | |
|
81 |
+ ((UInt32)data[i + 2] << 8) | |
|
82 |
+ ((UInt32)data[i + 3] & (~3)); |
|
83 |
+ |
|
84 |
+ UInt32 dest; |
|
85 |
+ if (encoding) |
|
86 |
+ dest = ip + (UInt32)i + src; |
|
87 |
+ else |
|
88 |
+ dest = src - (ip + (UInt32)i); |
|
89 |
+ data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); |
|
90 |
+ data[i + 1] = (Byte)(dest >> 16); |
|
91 |
+ data[i + 2] = (Byte)(dest >> 8); |
|
92 |
+ data[i + 3] &= 0x3; |
|
93 |
+ data[i + 3] |= dest; |
|
94 |
+ } |
|
95 |
+ } |
|
96 |
+ return i; |
|
97 |
+} |
|
98 |
+ |
|
99 |
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
100 |
+{ |
|
101 |
+ UInt32 i; |
|
102 |
+ if (size < 4) |
|
103 |
+ return 0; |
|
104 |
+ size -= 4; |
|
105 |
+ for (i = 0; i <= size; i += 4) |
|
106 |
+ { |
|
107 | 107 |
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || |
108 | 108 |
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) |
109 |
- { |
|
110 |
- UInt32 src = |
|
111 |
- ((UInt32)data[i + 0] << 24) | |
|
112 |
- ((UInt32)data[i + 1] << 16) | |
|
113 |
- ((UInt32)data[i + 2] << 8) | |
|
114 |
- ((UInt32)data[i + 3]); |
|
115 |
- UInt32 dest; |
|
116 |
- |
|
117 |
- src <<= 2; |
|
118 |
- if (encoding) |
|
119 |
- dest = ip + i + src; |
|
120 |
- else |
|
121 |
- dest = src - (ip + i); |
|
122 |
- dest >>= 2; |
|
123 |
- |
|
124 |
- dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; |
|
125 |
- |
|
126 |
- data[i + 0] = (Byte)(dest >> 24); |
|
127 |
- data[i + 1] = (Byte)(dest >> 16); |
|
128 |
- data[i + 2] = (Byte)(dest >> 8); |
|
129 |
- data[i + 3] = (Byte)dest; |
|
130 |
- } |
|
131 |
- } |
|
132 |
- return i; |
|
133 |
-} |
|
109 |
+ { |
|
110 |
+ UInt32 src = |
|
111 |
+ ((UInt32)data[i + 0] << 24) | |
|
112 |
+ ((UInt32)data[i + 1] << 16) | |
|
113 |
+ ((UInt32)data[i + 2] << 8) | |
|
114 |
+ ((UInt32)data[i + 3]); |
|
115 |
+ UInt32 dest; |
|
116 |
+ |
|
117 |
+ src <<= 2; |
|
118 |
+ if (encoding) |
|
119 |
+ dest = ip + i + src; |
|
120 |
+ else |
|
121 |
+ dest = src - (ip + i); |
|
122 |
+ dest >>= 2; |
|
123 |
+ |
|
124 |
+ dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; |
|
125 |
+ |
|
126 |
+ data[i + 0] = (Byte)(dest >> 24); |
|
127 |
+ data[i + 1] = (Byte)(dest >> 16); |
|
128 |
+ data[i + 2] = (Byte)(dest >> 8); |
|
129 |
+ data[i + 3] = (Byte)dest; |
|
130 |
+ } |
|
131 |
+ } |
|
132 |
+ return i; |
|
133 |
+} |
... | ... |
@@ -1,60 +1,60 @@ |
1 |
-/* Bra.h -- Branch converters for executables |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __BRA_H |
|
5 |
-#define __BRA_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-/* |
|
10 |
-These functions convert relative addresses to absolute addresses |
|
11 |
-in CALL instructions to increase the compression ratio. |
|
12 |
- |
|
13 |
- In: |
|
14 |
- data - data buffer |
|
15 |
- size - size of data |
|
16 |
- ip - current virtual Instruction Pinter (IP) value |
|
17 |
- state - state variable for x86 converter |
|
18 |
- encoding - 0 (for decoding), 1 (for encoding) |
|
19 |
- |
|
20 |
- Out: |
|
21 |
- state - state variable for x86 converter |
|
22 |
- |
|
23 |
- Returns: |
|
24 |
- The number of processed bytes. If you call these functions with multiple calls, |
|
25 |
- you must start next call with first byte after block of processed bytes. |
|
26 |
- |
|
27 |
- Type Endian Alignment LookAhead |
|
28 |
- |
|
29 |
- x86 little 1 4 |
|
30 |
- ARMT little 2 2 |
|
31 |
- ARM little 4 0 |
|
32 |
- PPC big 4 0 |
|
33 |
- SPARC big 4 0 |
|
34 |
- IA64 little 16 0 |
|
35 |
- |
|
36 |
- size must be >= Alignment + LookAhead, if it's not last block. |
|
37 |
- If (size < Alignment + LookAhead), converter returns 0. |
|
38 |
- |
|
39 |
- Example: |
|
40 |
- |
|
41 |
- UInt32 ip = 0; |
|
42 |
- for () |
|
43 |
- { |
|
44 |
- ; size must be >= Alignment + LookAhead, if it's not last block |
|
45 |
- SizeT processed = Convert(data, size, ip, 1); |
|
46 |
- data += processed; |
|
47 |
- size -= processed; |
|
48 |
- ip += processed; |
|
49 |
- } |
|
50 |
-*/ |
|
51 |
- |
|
52 |
-#define x86_Convert_Init(state) { state = 0; } |
|
53 |
-SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); |
|
54 |
-SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
55 |
-SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
56 |
-SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
57 |
-SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
58 |
-SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
59 |
- |
|
60 |
-#endif |
|
1 |
+/* Bra.h -- Branch converters for executables |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __BRA_H |
|
5 |
+#define __BRA_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+/* |
|
10 |
+These functions convert relative addresses to absolute addresses |
|
11 |
+in CALL instructions to increase the compression ratio. |
|
12 |
+ |
|
13 |
+ In: |
|
14 |
+ data - data buffer |
|
15 |
+ size - size of data |
|
16 |
+ ip - current virtual Instruction Pinter (IP) value |
|
17 |
+ state - state variable for x86 converter |
|
18 |
+ encoding - 0 (for decoding), 1 (for encoding) |
|
19 |
+ |
|
20 |
+ Out: |
|
21 |
+ state - state variable for x86 converter |
|
22 |
+ |
|
23 |
+ Returns: |
|
24 |
+ The number of processed bytes. If you call these functions with multiple calls, |
|
25 |
+ you must start next call with first byte after block of processed bytes. |
|
26 |
+ |
|
27 |
+ Type Endian Alignment LookAhead |
|
28 |
+ |
|
29 |
+ x86 little 1 4 |
|
30 |
+ ARMT little 2 2 |
|
31 |
+ ARM little 4 0 |
|
32 |
+ PPC big 4 0 |
|
33 |
+ SPARC big 4 0 |
|
34 |
+ IA64 little 16 0 |
|
35 |
+ |
|
36 |
+ size must be >= Alignment + LookAhead, if it's not last block. |
|
37 |
+ If (size < Alignment + LookAhead), converter returns 0. |
|
38 |
+ |
|
39 |
+ Example: |
|
40 |
+ |
|
41 |
+ UInt32 ip = 0; |
|
42 |
+ for () |
|
43 |
+ { |
|
44 |
+ ; size must be >= Alignment + LookAhead, if it's not last block |
|
45 |
+ SizeT processed = Convert(data, size, ip, 1); |
|
46 |
+ data += processed; |
|
47 |
+ size -= processed; |
|
48 |
+ ip += processed; |
|
49 |
+ } |
|
50 |
+*/ |
|
51 |
+ |
|
52 |
+#define x86_Convert_Init(state) { state = 0; } |
|
53 |
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); |
|
54 |
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
55 |
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
56 |
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
57 |
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
58 |
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
59 |
+ |
|
60 |
+#endif |
... | ... |
@@ -1,85 +1,85 @@ |
1 |
-/* Bra86.c -- Converter for x86 code (BCJ) |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bra.h" |
|
5 |
- |
|
6 |
-#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) |
|
7 |
- |
|
8 |
-const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; |
|
9 |
-const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; |
|
10 |
- |
|
11 |
-SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) |
|
12 |
-{ |
|
13 |
- SizeT bufferPos = 0, prevPosT; |
|
14 |
- UInt32 prevMask = *state & 0x7; |
|
15 |
- if (size < 5) |
|
16 |
- return 0; |
|
17 |
- ip += 5; |
|
18 |
- prevPosT = (SizeT)0 - 1; |
|
19 |
- |
|
20 |
- for (;;) |
|
21 |
- { |
|
22 |
- Byte *p = data + bufferPos; |
|
23 |
- Byte *limit = data + size - 4; |
|
24 |
- for (; p < limit; p++) |
|
25 |
- if ((*p & 0xFE) == 0xE8) |
|
26 |
- break; |
|
27 |
- bufferPos = (SizeT)(p - data); |
|
28 |
- if (p >= limit) |
|
29 |
- break; |
|
30 |
- prevPosT = bufferPos - prevPosT; |
|
31 |
- if (prevPosT > 3) |
|
32 |
- prevMask = 0; |
|
33 |
- else |
|
34 |
- { |
|
35 |
- prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; |
|
36 |
- if (prevMask != 0) |
|
37 |
- { |
|
38 |
- Byte b = p[4 - kMaskToBitNumber[prevMask]]; |
|
39 |
- if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) |
|
40 |
- { |
|
41 |
- prevPosT = bufferPos; |
|
42 |
- prevMask = ((prevMask << 1) & 0x7) | 1; |
|
43 |
- bufferPos++; |
|
44 |
- continue; |
|
45 |
- } |
|
46 |
- } |
|
47 |
- } |
|
48 |
- prevPosT = bufferPos; |
|
49 |
- |
|
50 |
- if (Test86MSByte(p[4])) |
|
51 |
- { |
|
52 |
- UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); |
|
53 |
- UInt32 dest; |
|
54 |
- for (;;) |
|
55 |
- { |
|
56 |
- Byte b; |
|
57 |
- int index; |
|
58 |
- if (encoding) |
|
59 |
- dest = (ip + (UInt32)bufferPos) + src; |
|
60 |
- else |
|
61 |
- dest = src - (ip + (UInt32)bufferPos); |
|
62 |
- if (prevMask == 0) |
|
63 |
- break; |
|
64 |
- index = kMaskToBitNumber[prevMask] * 8; |
|
65 |
- b = (Byte)(dest >> (24 - index)); |
|
66 |
- if (!Test86MSByte(b)) |
|
67 |
- break; |
|
68 |
- src = dest ^ ((1 << (32 - index)) - 1); |
|
69 |
- } |
|
70 |
- p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); |
|
71 |
- p[3] = (Byte)(dest >> 16); |
|
72 |
- p[2] = (Byte)(dest >> 8); |
|
73 |
- p[1] = (Byte)dest; |
|
74 |
- bufferPos += 5; |
|
75 |
- } |
|
76 |
- else |
|
77 |
- { |
|
78 |
- prevMask = ((prevMask << 1) & 0x7) | 1; |
|
79 |
- bufferPos++; |
|
80 |
- } |
|
81 |
- } |
|
82 |
- prevPosT = bufferPos - prevPosT; |
|
83 |
- *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); |
|
84 |
- return bufferPos; |
|
85 |
-} |
|
1 |
+/* Bra86.c -- Converter for x86 code (BCJ) |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bra.h" |
|
5 |
+ |
|
6 |
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) |
|
7 |
+ |
|
8 |
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; |
|
9 |
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; |
|
10 |
+ |
|
11 |
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) |
|
12 |
+{ |
|
13 |
+ SizeT bufferPos = 0, prevPosT; |
|
14 |
+ UInt32 prevMask = *state & 0x7; |
|
15 |
+ if (size < 5) |
|
16 |
+ return 0; |
|
17 |
+ ip += 5; |
|
18 |
+ prevPosT = (SizeT)0 - 1; |
|
19 |
+ |
|
20 |
+ for (;;) |
|
21 |
+ { |
|
22 |
+ Byte *p = data + bufferPos; |
|
23 |
+ Byte *limit = data + size - 4; |
|
24 |
+ for (; p < limit; p++) |
|
25 |
+ if ((*p & 0xFE) == 0xE8) |
|
26 |
+ break; |
|
27 |
+ bufferPos = (SizeT)(p - data); |
|
28 |
+ if (p >= limit) |
|
29 |
+ break; |
|
30 |
+ prevPosT = bufferPos - prevPosT; |
|
31 |
+ if (prevPosT > 3) |
|
32 |
+ prevMask = 0; |
|
33 |
+ else |
|
34 |
+ { |
|
35 |
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; |
|
36 |
+ if (prevMask != 0) |
|
37 |
+ { |
|
38 |
+ Byte b = p[4 - kMaskToBitNumber[prevMask]]; |
|
39 |
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) |
|
40 |
+ { |
|
41 |
+ prevPosT = bufferPos; |
|
42 |
+ prevMask = ((prevMask << 1) & 0x7) | 1; |
|
43 |
+ bufferPos++; |
|
44 |
+ continue; |
|
45 |
+ } |
|
46 |
+ } |
|
47 |
+ } |
|
48 |
+ prevPosT = bufferPos; |
|
49 |
+ |
|
50 |
+ if (Test86MSByte(p[4])) |
|
51 |
+ { |
|
52 |
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); |
|
53 |
+ UInt32 dest; |
|
54 |
+ for (;;) |
|
55 |
+ { |
|
56 |
+ Byte b; |
|
57 |
+ int index; |
|
58 |
+ if (encoding) |
|
59 |
+ dest = (ip + (UInt32)bufferPos) + src; |
|
60 |
+ else |
|
61 |
+ dest = src - (ip + (UInt32)bufferPos); |
|
62 |
+ if (prevMask == 0) |
|
63 |
+ break; |
|
64 |
+ index = kMaskToBitNumber[prevMask] * 8; |
|
65 |
+ b = (Byte)(dest >> (24 - index)); |
|
66 |
+ if (!Test86MSByte(b)) |
|
67 |
+ break; |
|
68 |
+ src = dest ^ ((1 << (32 - index)) - 1); |
|
69 |
+ } |
|
70 |
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); |
|
71 |
+ p[3] = (Byte)(dest >> 16); |
|
72 |
+ p[2] = (Byte)(dest >> 8); |
|
73 |
+ p[1] = (Byte)dest; |
|
74 |
+ bufferPos += 5; |
|
75 |
+ } |
|
76 |
+ else |
|
77 |
+ { |
|
78 |
+ prevMask = ((prevMask << 1) & 0x7) | 1; |
|
79 |
+ bufferPos++; |
|
80 |
+ } |
|
81 |
+ } |
|
82 |
+ prevPosT = bufferPos - prevPosT; |
|
83 |
+ *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); |
|
84 |
+ return bufferPos; |
|
85 |
+} |
... | ... |
@@ -1,67 +1,67 @@ |
1 |
-/* BraIA64.c -- Converter for IA-64 code |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bra.h" |
|
5 |
- |
|
6 |
-static const Byte kBranchTable[32] = |
|
7 |
-{ |
|
8 |
- 0, 0, 0, 0, 0, 0, 0, 0, |
|
9 |
- 0, 0, 0, 0, 0, 0, 0, 0, |
|
10 |
- 4, 4, 6, 6, 0, 0, 7, 7, |
|
11 |
- 4, 4, 0, 0, 4, 4, 0, 0 |
|
12 |
-}; |
|
13 |
- |
|
14 |
-SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
15 |
-{ |
|
16 |
- SizeT i; |
|
17 |
- if (size < 16) |
|
18 |
- return 0; |
|
19 |
- size -= 16; |
|
20 |
- for (i = 0; i <= size; i += 16) |
|
21 |
- { |
|
22 |
- UInt32 instrTemplate = data[i] & 0x1F; |
|
23 |
- UInt32 mask = kBranchTable[instrTemplate]; |
|
24 |
- UInt32 bitPos = 5; |
|
25 |
- int slot; |
|
26 |
- for (slot = 0; slot < 3; slot++, bitPos += 41) |
|
27 |
- { |
|
28 |
- UInt32 bytePos, bitRes; |
|
29 |
- UInt64 instruction, instNorm; |
|
30 |
- int j; |
|
31 |
- if (((mask >> slot) & 1) == 0) |
|
32 |
- continue; |
|
33 |
- bytePos = (bitPos >> 3); |
|
34 |
- bitRes = bitPos & 0x7; |
|
35 |
- instruction = 0; |
|
36 |
- for (j = 0; j < 6; j++) |
|
37 |
- instruction += (UInt64)data[i + j + bytePos] << (8 * j); |
|
38 |
- |
|
39 |
- instNorm = instruction >> bitRes; |
|
40 |
- if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) |
|
41 |
- { |
|
42 |
- UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); |
|
43 |
- UInt32 dest; |
|
44 |
- src |= ((UInt32)(instNorm >> 36) & 1) << 20; |
|
45 |
- |
|
46 |
- src <<= 4; |
|
47 |
- |
|
48 |
- if (encoding) |
|
49 |
- dest = ip + (UInt32)i + src; |
|
50 |
- else |
|
51 |
- dest = src - (ip + (UInt32)i); |
|
52 |
- |
|
53 |
- dest >>= 4; |
|
54 |
- |
|
55 |
- instNorm &= ~((UInt64)(0x8FFFFF) << 13); |
|
56 |
- instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); |
|
57 |
- instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); |
|
58 |
- |
|
59 |
- instruction &= (1 << bitRes) - 1; |
|
60 |
- instruction |= (instNorm << bitRes); |
|
61 |
- for (j = 0; j < 6; j++) |
|
62 |
- data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); |
|
63 |
- } |
|
64 |
- } |
|
65 |
- } |
|
66 |
- return i; |
|
67 |
-} |
|
1 |
+/* BraIA64.c -- Converter for IA-64 code |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bra.h" |
|
5 |
+ |
|
6 |
+static const Byte kBranchTable[32] = |
|
7 |
+{ |
|
8 |
+ 0, 0, 0, 0, 0, 0, 0, 0, |
|
9 |
+ 0, 0, 0, 0, 0, 0, 0, 0, |
|
10 |
+ 4, 4, 6, 6, 0, 0, 7, 7, |
|
11 |
+ 4, 4, 0, 0, 4, 4, 0, 0 |
|
12 |
+}; |
|
13 |
+ |
|
14 |
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
15 |
+{ |
|
16 |
+ SizeT i; |
|
17 |
+ if (size < 16) |
|
18 |
+ return 0; |
|
19 |
+ size -= 16; |
|
20 |
+ for (i = 0; i <= size; i += 16) |
|
21 |
+ { |
|
22 |
+ UInt32 instrTemplate = data[i] & 0x1F; |
|
23 |
+ UInt32 mask = kBranchTable[instrTemplate]; |
|
24 |
+ UInt32 bitPos = 5; |
|
25 |
+ int slot; |
|
26 |
+ for (slot = 0; slot < 3; slot++, bitPos += 41) |
|
27 |
+ { |
|
28 |
+ UInt32 bytePos, bitRes; |
|
29 |
+ UInt64 instruction, instNorm; |
|
30 |
+ int j; |
|
31 |
+ if (((mask >> slot) & 1) == 0) |
|
32 |
+ continue; |
|
33 |
+ bytePos = (bitPos >> 3); |
|
34 |
+ bitRes = bitPos & 0x7; |
|
35 |
+ instruction = 0; |
|
36 |
+ for (j = 0; j < 6; j++) |
|
37 |
+ instruction += (UInt64)data[i + j + bytePos] << (8 * j); |
|
38 |
+ |
|
39 |
+ instNorm = instruction >> bitRes; |
|
40 |
+ if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) |
|
41 |
+ { |
|
42 |
+ UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); |
|
43 |
+ UInt32 dest; |
|
44 |
+ src |= ((UInt32)(instNorm >> 36) & 1) << 20; |
|
45 |
+ |
|
46 |
+ src <<= 4; |
|
47 |
+ |
|
48 |
+ if (encoding) |
|
49 |
+ dest = ip + (UInt32)i + src; |
|
50 |
+ else |
|
51 |
+ dest = src - (ip + (UInt32)i); |
|
52 |
+ |
|
53 |
+ dest >>= 4; |
|
54 |
+ |
|
55 |
+ instNorm &= ~((UInt64)(0x8FFFFF) << 13); |
|
56 |
+ instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); |
|
57 |
+ instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); |
|
58 |
+ |
|
59 |
+ instruction &= (1 << bitRes) - 1; |
|
60 |
+ instruction |= (instNorm << bitRes); |
|
61 |
+ for (j = 0; j < 6; j++) |
|
62 |
+ data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); |
|
63 |
+ } |
|
64 |
+ } |
|
65 |
+ } |
|
66 |
+ return i; |
|
67 |
+} |
... | ... |
@@ -1,69 +1,69 @@ |
1 |
-/* CpuArch.h |
|
2 |
-2008-08-05 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#ifndef __CPUARCH_H |
|
7 |
-#define __CPUARCH_H |
|
8 |
- |
|
9 |
-/* |
|
10 |
-LITTLE_ENDIAN_UNALIGN means: |
|
11 |
- 1) CPU is LITTLE_ENDIAN |
|
12 |
- 2) it's allowed to make unaligned memory accesses |
|
13 |
-if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know |
|
14 |
-about these properties of platform. |
|
15 |
-*/ |
|
16 |
- |
|
17 |
-#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) |
|
18 |
-#define LITTLE_ENDIAN_UNALIGN |
|
19 |
-#endif |
|
20 |
- |
|
21 |
-#ifdef LITTLE_ENDIAN_UNALIGN |
|
22 |
- |
|
23 |
-#define GetUi16(p) (*(const UInt16 *)(p)) |
|
24 |
-#define GetUi32(p) (*(const UInt32 *)(p)) |
|
25 |
-#define GetUi64(p) (*(const UInt64 *)(p)) |
|
26 |
-#define SetUi32(p, d) *(UInt32 *)(p) = (d); |
|
27 |
- |
|
28 |
-#else |
|
29 |
- |
|
30 |
-#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) |
|
31 |
- |
|
32 |
-#define GetUi32(p) ( \ |
|
33 |
- ((const Byte *)(p))[0] | \ |
|
34 |
- ((UInt32)((const Byte *)(p))[1] << 8) | \ |
|
35 |
- ((UInt32)((const Byte *)(p))[2] << 16) | \ |
|
36 |
- ((UInt32)((const Byte *)(p))[3] << 24)) |
|
37 |
- |
|
38 |
-#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) |
|
39 |
- |
|
40 |
-#define SetUi32(p, d) { UInt32 _x_ = (d); \ |
|
41 |
- ((Byte *)(p))[0] = (Byte)_x_; \ |
|
42 |
- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ |
|
43 |
- ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ |
|
44 |
- ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } |
|
45 |
- |
|
46 |
-#endif |
|
47 |
- |
|
48 |
-#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) |
|
49 |
- |
|
50 |
-#pragma intrinsic(_byteswap_ulong) |
|
51 |
-#pragma intrinsic(_byteswap_uint64) |
|
52 |
-#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) |
|
53 |
-#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) |
|
54 |
- |
|
55 |
-#else |
|
56 |
- |
|
57 |
-#define GetBe32(p) ( \ |
|
58 |
- ((UInt32)((const Byte *)(p))[0] << 24) | \ |
|
59 |
- ((UInt32)((const Byte *)(p))[1] << 16) | \ |
|
60 |
- ((UInt32)((const Byte *)(p))[2] << 8) | \ |
|
61 |
- ((const Byte *)(p))[3] ) |
|
62 |
- |
|
63 |
-#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) |
|
64 |
- |
|
65 |
-#endif |
|
66 |
- |
|
67 |
-#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) |
|
68 |
- |
|
69 |
-#endif |
|
1 |
+/* CpuArch.h |
|
2 |
+2008-08-05 |
|
3 |
+Igor Pavlov |
|
4 |
+Public domain */ |
|
5 |
+ |
|
6 |
+#ifndef __CPUARCH_H |
|
7 |
+#define __CPUARCH_H |
|
8 |
+ |
|
9 |
+/* |
|
10 |
+LITTLE_ENDIAN_UNALIGN means: |
|
11 |
+ 1) CPU is LITTLE_ENDIAN |
|
12 |
+ 2) it's allowed to make unaligned memory accesses |
|
13 |
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know |
|
14 |
+about these properties of platform. |
|
15 |
+*/ |
|
16 |
+ |
|
17 |
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) |
|
18 |
+#define LITTLE_ENDIAN_UNALIGN |
|
19 |
+#endif |
|
20 |
+ |
|
21 |
+#ifdef LITTLE_ENDIAN_UNALIGN |
|
22 |
+ |
|
23 |
+#define GetUi16(p) (*(const UInt16 *)(p)) |
|
24 |
+#define GetUi32(p) (*(const UInt32 *)(p)) |
|
25 |
+#define GetUi64(p) (*(const UInt64 *)(p)) |
|
26 |
+#define SetUi32(p, d) *(UInt32 *)(p) = (d); |
|
27 |
+ |
|
28 |
+#else |
|
29 |
+ |
|
30 |
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) |
|
31 |
+ |
|
32 |
+#define GetUi32(p) ( \ |
|
33 |
+ ((const Byte *)(p))[0] | \ |
|
34 |
+ ((UInt32)((const Byte *)(p))[1] << 8) | \ |
|
35 |
+ ((UInt32)((const Byte *)(p))[2] << 16) | \ |
|
36 |
+ ((UInt32)((const Byte *)(p))[3] << 24)) |
|
37 |
+ |
|
38 |
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) |
|
39 |
+ |
|
40 |
+#define SetUi32(p, d) { UInt32 _x_ = (d); \ |
|
41 |
+ ((Byte *)(p))[0] = (Byte)_x_; \ |
|
42 |
+ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ |
|
43 |
+ ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ |
|
44 |
+ ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } |
|
45 |
+ |
|
46 |
+#endif |
|
47 |
+ |
|
48 |
+#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) |
|
49 |
+ |
|
50 |
+#pragma intrinsic(_byteswap_ulong) |
|
51 |
+#pragma intrinsic(_byteswap_uint64) |
|
52 |
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) |
|
53 |
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) |
|
54 |
+ |
|
55 |
+#else |
|
56 |
+ |
|
57 |
+#define GetBe32(p) ( \ |
|
58 |
+ ((UInt32)((const Byte *)(p))[0] << 24) | \ |
|
59 |
+ ((UInt32)((const Byte *)(p))[1] << 16) | \ |
|
60 |
+ ((UInt32)((const Byte *)(p))[2] << 8) | \ |
|
61 |
+ ((const Byte *)(p))[3] ) |
|
62 |
+ |
|
63 |
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) |
|
64 |
+ |
|
65 |
+#endif |
|
66 |
+ |
|
67 |
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) |
|
68 |
+ |
|
69 |
+#endif |
... | ... |
@@ -1,1007 +1,1007 @@ |
1 |
-/* LzmaDec.c -- LZMA Decoder |
|
2 |
-2008-11-06 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "LzmaDec.h" |
|
5 |
- |
|
6 |
-#include <string.h> |
|
7 |
- |
|
8 |
-#define kNumTopBits 24 |
|
9 |
-#define kTopValue ((UInt32)1 << kNumTopBits) |
|
10 |
- |
|
11 |
-#define kNumBitModelTotalBits 11 |
|
12 |
-#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
13 |
-#define kNumMoveBits 5 |
|
14 |
- |
|
15 |
-#define RC_INIT_SIZE 5 |
|
16 |
- |
|
17 |
-#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } |
|
18 |
- |
|
19 |
-#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
20 |
-#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); |
|
21 |
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); |
|
22 |
-#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ |
|
23 |
- { UPDATE_0(p); i = (i + i); A0; } else \ |
|
24 |
- { UPDATE_1(p); i = (i + i) + 1; A1; } |
|
25 |
-#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) |
|
26 |
- |
|
27 |
-#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } |
|
28 |
-#define TREE_DECODE(probs, limit, i) \ |
|
29 |
- { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } |
|
30 |
- |
|
31 |
-/* #define _LZMA_SIZE_OPT */ |
|
32 |
- |
|
33 |
-#ifdef _LZMA_SIZE_OPT |
|
34 |
-#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) |
|
35 |
-#else |
|
36 |
-#define TREE_6_DECODE(probs, i) \ |
|
37 |
- { i = 1; \ |
|
38 |
- TREE_GET_BIT(probs, i); \ |
|
39 |
- TREE_GET_BIT(probs, i); \ |
|
40 |
- TREE_GET_BIT(probs, i); \ |
|
41 |
- TREE_GET_BIT(probs, i); \ |
|
42 |
- TREE_GET_BIT(probs, i); \ |
|
43 |
- TREE_GET_BIT(probs, i); \ |
|
44 |
- i -= 0x40; } |
|
45 |
-#endif |
|
46 |
- |
|
47 |
-#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } |
|
48 |
- |
|
49 |
-#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
50 |
-#define UPDATE_0_CHECK range = bound; |
|
51 |
-#define UPDATE_1_CHECK range -= bound; code -= bound; |
|
52 |
-#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ |
|
53 |
- { UPDATE_0_CHECK; i = (i + i); A0; } else \ |
|
54 |
- { UPDATE_1_CHECK; i = (i + i) + 1; A1; } |
|
55 |
-#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) |
|
56 |
-#define TREE_DECODE_CHECK(probs, limit, i) \ |
|
57 |
- { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } |
|
58 |
- |
|
59 |
- |
|
60 |
-#define kNumPosBitsMax 4 |
|
61 |
-#define kNumPosStatesMax (1 << kNumPosBitsMax) |
|
62 |
- |
|
63 |
-#define kLenNumLowBits 3 |
|
64 |
-#define kLenNumLowSymbols (1 << kLenNumLowBits) |
|
65 |
-#define kLenNumMidBits 3 |
|
66 |
-#define kLenNumMidSymbols (1 << kLenNumMidBits) |
|
67 |
-#define kLenNumHighBits 8 |
|
68 |
-#define kLenNumHighSymbols (1 << kLenNumHighBits) |
|
69 |
- |
|
70 |
-#define LenChoice 0 |
|
71 |
-#define LenChoice2 (LenChoice + 1) |
|
72 |
-#define LenLow (LenChoice2 + 1) |
|
73 |
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) |
|
74 |
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) |
|
75 |
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols) |
|
76 |
- |
|
77 |
- |
|
78 |
-#define kNumStates 12 |
|
79 |
-#define kNumLitStates 7 |
|
80 |
- |
|
81 |
-#define kStartPosModelIndex 4 |
|
82 |
-#define kEndPosModelIndex 14 |
|
83 |
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) |
|
84 |
- |
|
85 |
-#define kNumPosSlotBits 6 |
|
86 |
-#define kNumLenToPosStates 4 |
|
87 |
- |
|
88 |
-#define kNumAlignBits 4 |
|
89 |
-#define kAlignTableSize (1 << kNumAlignBits) |
|
90 |
- |
|
91 |
-#define kMatchMinLen 2 |
|
92 |
-#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) |
|
93 |
- |
|
94 |
-#define IsMatch 0 |
|
95 |
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) |
|
96 |
-#define IsRepG0 (IsRep + kNumStates) |
|
97 |
-#define IsRepG1 (IsRepG0 + kNumStates) |
|
98 |
-#define IsRepG2 (IsRepG1 + kNumStates) |
|
99 |
-#define IsRep0Long (IsRepG2 + kNumStates) |
|
100 |
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) |
|
101 |
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) |
|
102 |
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) |
|
103 |
-#define LenCoder (Align + kAlignTableSize) |
|
104 |
-#define RepLenCoder (LenCoder + kNumLenProbs) |
|
105 |
-#define Literal (RepLenCoder + kNumLenProbs) |
|
106 |
- |
|
107 |
-#define LZMA_BASE_SIZE 1846 |
|
108 |
-#define LZMA_LIT_SIZE 768 |
|
109 |
- |
|
110 |
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) |
|
111 |
- |
|
112 |
-#if Literal != LZMA_BASE_SIZE |
|
113 |
-StopCompilingDueBUG |
|
114 |
-#endif |
|
115 |
- |
|
116 |
-static const Byte kLiteralNextStates[kNumStates * 2] = |
|
117 |
-{ |
|
118 |
- 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, |
|
119 |
- 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 |
|
120 |
-}; |
|
121 |
- |
|
122 |
-#define LZMA_DIC_MIN (1 << 12) |
|
123 |
- |
|
124 |
-/* First LZMA-symbol is always decoded. |
|
125 |
-And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization |
|
126 |
-Out: |
|
127 |
- Result: |
|
128 |
- SZ_OK - OK |
|
129 |
- SZ_ERROR_DATA - Error |
|
130 |
- p->remainLen: |
|
131 |
- < kMatchSpecLenStart : normal remain |
|
132 |
- = kMatchSpecLenStart : finished |
|
133 |
- = kMatchSpecLenStart + 1 : Flush marker |
|
134 |
- = kMatchSpecLenStart + 2 : State Init Marker |
|
135 |
-*/ |
|
136 |
- |
|
137 |
-static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
138 |
-{ |
|
139 |
- CLzmaProb *probs = p->probs; |
|
140 |
- |
|
141 |
- unsigned state = p->state; |
|
142 |
- UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; |
|
143 |
- unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; |
|
144 |
- unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; |
|
145 |
- unsigned lc = p->prop.lc; |
|
146 |
- |
|
147 |
- Byte *dic = p->dic; |
|
148 |
- SizeT dicBufSize = p->dicBufSize; |
|
149 |
- SizeT dicPos = p->dicPos; |
|
150 |
- |
|
151 |
- UInt32 processedPos = p->processedPos; |
|
152 |
- UInt32 checkDicSize = p->checkDicSize; |
|
153 |
- unsigned len = 0; |
|
154 |
- |
|
155 |
- const Byte *buf = p->buf; |
|
156 |
- UInt32 range = p->range; |
|
157 |
- UInt32 code = p->code; |
|
158 |
- |
|
159 |
- do |
|
160 |
- { |
|
161 |
- CLzmaProb *prob; |
|
162 |
- UInt32 bound; |
|
163 |
- unsigned ttt; |
|
164 |
- unsigned posState = processedPos & pbMask; |
|
165 |
- |
|
166 |
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
167 |
- IF_BIT_0(prob) |
|
168 |
- { |
|
169 |
- unsigned symbol; |
|
170 |
- UPDATE_0(prob); |
|
171 |
- prob = probs + Literal; |
|
172 |
- if (checkDicSize != 0 || processedPos != 0) |
|
173 |
- prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + |
|
174 |
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); |
|
175 |
- |
|
176 |
- if (state < kNumLitStates) |
|
177 |
- { |
|
178 |
- symbol = 1; |
|
179 |
- do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); |
|
180 |
- } |
|
181 |
- else |
|
182 |
- { |
|
183 |
- unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
184 |
- unsigned offs = 0x100; |
|
185 |
- symbol = 1; |
|
186 |
- do |
|
187 |
- { |
|
188 |
- unsigned bit; |
|
189 |
- CLzmaProb *probLit; |
|
190 |
- matchByte <<= 1; |
|
191 |
- bit = (matchByte & offs); |
|
192 |
- probLit = prob + offs + bit + symbol; |
|
193 |
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) |
|
194 |
- } |
|
195 |
- while (symbol < 0x100); |
|
196 |
- } |
|
197 |
- dic[dicPos++] = (Byte)symbol; |
|
198 |
- processedPos++; |
|
199 |
- |
|
200 |
- state = kLiteralNextStates[state]; |
|
201 |
- /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ |
|
202 |
- continue; |
|
203 |
- } |
|
204 |
- else |
|
205 |
- { |
|
206 |
- UPDATE_1(prob); |
|
207 |
- prob = probs + IsRep + state; |
|
208 |
- IF_BIT_0(prob) |
|
209 |
- { |
|
210 |
- UPDATE_0(prob); |
|
211 |
- state += kNumStates; |
|
212 |
- prob = probs + LenCoder; |
|
213 |
- } |
|
214 |
- else |
|
215 |
- { |
|
216 |
- UPDATE_1(prob); |
|
217 |
- if (checkDicSize == 0 && processedPos == 0) |
|
218 |
- return SZ_ERROR_DATA; |
|
219 |
- prob = probs + IsRepG0 + state; |
|
220 |
- IF_BIT_0(prob) |
|
221 |
- { |
|
222 |
- UPDATE_0(prob); |
|
223 |
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
224 |
- IF_BIT_0(prob) |
|
225 |
- { |
|
226 |
- UPDATE_0(prob); |
|
227 |
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
228 |
- dicPos++; |
|
229 |
- processedPos++; |
|
230 |
- state = state < kNumLitStates ? 9 : 11; |
|
231 |
- continue; |
|
232 |
- } |
|
233 |
- UPDATE_1(prob); |
|
234 |
- } |
|
235 |
- else |
|
236 |
- { |
|
237 |
- UInt32 distance; |
|
238 |
- UPDATE_1(prob); |
|
239 |
- prob = probs + IsRepG1 + state; |
|
240 |
- IF_BIT_0(prob) |
|
241 |
- { |
|
242 |
- UPDATE_0(prob); |
|
243 |
- distance = rep1; |
|
244 |
- } |
|
245 |
- else |
|
246 |
- { |
|
247 |
- UPDATE_1(prob); |
|
248 |
- prob = probs + IsRepG2 + state; |
|
249 |
- IF_BIT_0(prob) |
|
250 |
- { |
|
251 |
- UPDATE_0(prob); |
|
252 |
- distance = rep2; |
|
253 |
- } |
|
254 |
- else |
|
255 |
- { |
|
256 |
- UPDATE_1(prob); |
|
257 |
- distance = rep3; |
|
258 |
- rep3 = rep2; |
|
259 |
- } |
|
260 |
- rep2 = rep1; |
|
261 |
- } |
|
262 |
- rep1 = rep0; |
|
263 |
- rep0 = distance; |
|
264 |
- } |
|
265 |
- state = state < kNumLitStates ? 8 : 11; |
|
266 |
- prob = probs + RepLenCoder; |
|
267 |
- } |
|
268 |
- { |
|
269 |
- unsigned limit, offset; |
|
270 |
- CLzmaProb *probLen = prob + LenChoice; |
|
271 |
- IF_BIT_0(probLen) |
|
272 |
- { |
|
273 |
- UPDATE_0(probLen); |
|
274 |
- probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
275 |
- offset = 0; |
|
276 |
- limit = (1 << kLenNumLowBits); |
|
277 |
- } |
|
278 |
- else |
|
279 |
- { |
|
280 |
- UPDATE_1(probLen); |
|
281 |
- probLen = prob + LenChoice2; |
|
282 |
- IF_BIT_0(probLen) |
|
283 |
- { |
|
284 |
- UPDATE_0(probLen); |
|
285 |
- probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
286 |
- offset = kLenNumLowSymbols; |
|
287 |
- limit = (1 << kLenNumMidBits); |
|
288 |
- } |
|
289 |
- else |
|
290 |
- { |
|
291 |
- UPDATE_1(probLen); |
|
292 |
- probLen = prob + LenHigh; |
|
293 |
- offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
294 |
- limit = (1 << kLenNumHighBits); |
|
295 |
- } |
|
296 |
- } |
|
297 |
- TREE_DECODE(probLen, limit, len); |
|
298 |
- len += offset; |
|
299 |
- } |
|
300 |
- |
|
301 |
- if (state >= kNumStates) |
|
302 |
- { |
|
303 |
- UInt32 distance; |
|
304 |
- prob = probs + PosSlot + |
|
305 |
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); |
|
306 |
- TREE_6_DECODE(prob, distance); |
|
307 |
- if (distance >= kStartPosModelIndex) |
|
308 |
- { |
|
309 |
- unsigned posSlot = (unsigned)distance; |
|
310 |
- int numDirectBits = (int)(((distance >> 1) - 1)); |
|
311 |
- distance = (2 | (distance & 1)); |
|
312 |
- if (posSlot < kEndPosModelIndex) |
|
313 |
- { |
|
314 |
- distance <<= numDirectBits; |
|
315 |
- prob = probs + SpecPos + distance - posSlot - 1; |
|
316 |
- { |
|
317 |
- UInt32 mask = 1; |
|
318 |
- unsigned i = 1; |
|
319 |
- do |
|
320 |
- { |
|
321 |
- GET_BIT2(prob + i, i, ; , distance |= mask); |
|
322 |
- mask <<= 1; |
|
323 |
- } |
|
324 |
- while (--numDirectBits != 0); |
|
325 |
- } |
|
326 |
- } |
|
327 |
- else |
|
328 |
- { |
|
329 |
- numDirectBits -= kNumAlignBits; |
|
330 |
- do |
|
331 |
- { |
|
332 |
- NORMALIZE |
|
333 |
- range >>= 1; |
|
334 |
- |
|
335 |
- { |
|
336 |
- UInt32 t; |
|
337 |
- code -= range; |
|
338 |
- t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ |
|
339 |
- distance = (distance << 1) + (t + 1); |
|
340 |
- code += range & t; |
|
341 |
- } |
|
342 |
- /* |
|
343 |
- distance <<= 1; |
|
344 |
- if (code >= range) |
|
345 |
- { |
|
346 |
- code -= range; |
|
347 |
- distance |= 1; |
|
348 |
- } |
|
349 |
- */ |
|
350 |
- } |
|
351 |
- while (--numDirectBits != 0); |
|
352 |
- prob = probs + Align; |
|
353 |
- distance <<= kNumAlignBits; |
|
354 |
- { |
|
355 |
- unsigned i = 1; |
|
356 |
- GET_BIT2(prob + i, i, ; , distance |= 1); |
|
357 |
- GET_BIT2(prob + i, i, ; , distance |= 2); |
|
358 |
- GET_BIT2(prob + i, i, ; , distance |= 4); |
|
359 |
- GET_BIT2(prob + i, i, ; , distance |= 8); |
|
360 |
- } |
|
361 |
- if (distance == (UInt32)0xFFFFFFFF) |
|
362 |
- { |
|
363 |
- len += kMatchSpecLenStart; |
|
364 |
- state -= kNumStates; |
|
365 |
- break; |
|
366 |
- } |
|
367 |
- } |
|
368 |
- } |
|
369 |
- rep3 = rep2; |
|
370 |
- rep2 = rep1; |
|
371 |
- rep1 = rep0; |
|
372 |
- rep0 = distance + 1; |
|
373 |
- if (checkDicSize == 0) |
|
374 |
- { |
|
375 |
- if (distance >= processedPos) |
|
376 |
- return SZ_ERROR_DATA; |
|
377 |
- } |
|
378 |
- else if (distance >= checkDicSize) |
|
379 |
- return SZ_ERROR_DATA; |
|
380 |
- state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; |
|
381 |
- /* state = kLiteralNextStates[state]; */ |
|
382 |
- } |
|
383 |
- |
|
384 |
- len += kMatchMinLen; |
|
385 |
- |
|
386 |
- if (limit == dicPos) |
|
387 |
- return SZ_ERROR_DATA; |
|
388 |
- { |
|
389 |
- SizeT rem = limit - dicPos; |
|
390 |
- unsigned curLen = ((rem < len) ? (unsigned)rem : len); |
|
391 |
- SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); |
|
392 |
- |
|
393 |
- processedPos += curLen; |
|
394 |
- |
|
395 |
- len -= curLen; |
|
396 |
- if (pos + curLen <= dicBufSize) |
|
397 |
- { |
|
398 |
- Byte *dest = dic + dicPos; |
|
399 |
- ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; |
|
400 |
- const Byte *lim = dest + curLen; |
|
401 |
- dicPos += curLen; |
|
402 |
- do |
|
403 |
- *(dest) = (Byte)*(dest + src); |
|
404 |
- while (++dest != lim); |
|
405 |
- } |
|
406 |
- else |
|
407 |
- { |
|
408 |
- do |
|
409 |
- { |
|
410 |
- dic[dicPos++] = dic[pos]; |
|
411 |
- if (++pos == dicBufSize) |
|
412 |
- pos = 0; |
|
413 |
- } |
|
414 |
- while (--curLen != 0); |
|
415 |
- } |
|
416 |
- } |
|
417 |
- } |
|
418 |
- } |
|
419 |
- while (dicPos < limit && buf < bufLimit); |
|
420 |
- NORMALIZE; |
|
421 |
- p->buf = buf; |
|
422 |
- p->range = range; |
|
423 |
- p->code = code; |
|
424 |
- p->remainLen = len; |
|
425 |
- p->dicPos = dicPos; |
|
426 |
- p->processedPos = processedPos; |
|
427 |
- p->reps[0] = rep0; |
|
428 |
- p->reps[1] = rep1; |
|
429 |
- p->reps[2] = rep2; |
|
430 |
- p->reps[3] = rep3; |
|
431 |
- p->state = state; |
|
432 |
- |
|
433 |
- return SZ_OK; |
|
434 |
-} |
|
435 |
- |
|
436 |
-static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) |
|
437 |
-{ |
|
438 |
- if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) |
|
439 |
- { |
|
440 |
- Byte *dic = p->dic; |
|
441 |
- SizeT dicPos = p->dicPos; |
|
442 |
- SizeT dicBufSize = p->dicBufSize; |
|
443 |
- unsigned len = p->remainLen; |
|
444 |
- UInt32 rep0 = p->reps[0]; |
|
445 |
- if (limit - dicPos < len) |
|
446 |
- len = (unsigned)(limit - dicPos); |
|
447 |
- |
|
448 |
- if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) |
|
449 |
- p->checkDicSize = p->prop.dicSize; |
|
450 |
- |
|
451 |
- p->processedPos += len; |
|
452 |
- p->remainLen -= len; |
|
453 |
- while (len-- != 0) |
|
454 |
- { |
|
455 |
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
456 |
- dicPos++; |
|
457 |
- } |
|
458 |
- p->dicPos = dicPos; |
|
459 |
- } |
|
460 |
-} |
|
461 |
- |
|
462 |
-static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
463 |
-{ |
|
464 |
- do |
|
465 |
- { |
|
466 |
- SizeT limit2 = limit; |
|
467 |
- if (p->checkDicSize == 0) |
|
468 |
- { |
|
469 |
- UInt32 rem = p->prop.dicSize - p->processedPos; |
|
470 |
- if (limit - p->dicPos > rem) |
|
471 |
- limit2 = p->dicPos + rem; |
|
472 |
- } |
|
473 |
- RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); |
|
474 |
- if (p->processedPos >= p->prop.dicSize) |
|
475 |
- p->checkDicSize = p->prop.dicSize; |
|
476 |
- LzmaDec_WriteRem(p, limit); |
|
477 |
- } |
|
478 |
- while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); |
|
479 |
- |
|
480 |
- if (p->remainLen > kMatchSpecLenStart) |
|
481 |
- { |
|
482 |
- p->remainLen = kMatchSpecLenStart; |
|
483 |
- } |
|
484 |
- return 0; |
|
485 |
-} |
|
486 |
- |
|
487 |
-typedef enum |
|
488 |
-{ |
|
489 |
- DUMMY_ERROR, /* unexpected end of input stream */ |
|
490 |
- DUMMY_LIT, |
|
491 |
- DUMMY_MATCH, |
|
492 |
- DUMMY_REP |
|
493 |
-} ELzmaDummy; |
|
494 |
- |
|
495 |
-static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) |
|
496 |
-{ |
|
497 |
- UInt32 range = p->range; |
|
498 |
- UInt32 code = p->code; |
|
499 |
- const Byte *bufLimit = buf + inSize; |
|
500 |
- CLzmaProb *probs = p->probs; |
|
501 |
- unsigned state = p->state; |
|
502 |
- ELzmaDummy res; |
|
503 |
- |
|
504 |
- { |
|
505 |
- CLzmaProb *prob; |
|
506 |
- UInt32 bound; |
|
507 |
- unsigned ttt; |
|
508 |
- unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); |
|
509 |
- |
|
510 |
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
511 |
- IF_BIT_0_CHECK(prob) |
|
512 |
- { |
|
513 |
- UPDATE_0_CHECK |
|
514 |
- |
|
515 |
- /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ |
|
516 |
- |
|
517 |
- prob = probs + Literal; |
|
518 |
- if (p->checkDicSize != 0 || p->processedPos != 0) |
|
519 |
- prob += (LZMA_LIT_SIZE * |
|
520 |
- ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + |
|
521 |
- (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); |
|
522 |
- |
|
523 |
- if (state < kNumLitStates) |
|
524 |
- { |
|
525 |
- unsigned symbol = 1; |
|
526 |
- do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); |
|
527 |
- } |
|
528 |
- else |
|
529 |
- { |
|
530 |
- unsigned matchByte = p->dic[p->dicPos - p->reps[0] + |
|
531 |
- ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; |
|
532 |
- unsigned offs = 0x100; |
|
533 |
- unsigned symbol = 1; |
|
534 |
- do |
|
535 |
- { |
|
536 |
- unsigned bit; |
|
537 |
- CLzmaProb *probLit; |
|
538 |
- matchByte <<= 1; |
|
539 |
- bit = (matchByte & offs); |
|
540 |
- probLit = prob + offs + bit + symbol; |
|
541 |
- GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) |
|
542 |
- } |
|
543 |
- while (symbol < 0x100); |
|
544 |
- } |
|
545 |
- res = DUMMY_LIT; |
|
546 |
- } |
|
547 |
- else |
|
548 |
- { |
|
549 |
- unsigned len; |
|
550 |
- UPDATE_1_CHECK; |
|
551 |
- |
|
552 |
- prob = probs + IsRep + state; |
|
553 |
- IF_BIT_0_CHECK(prob) |
|
554 |
- { |
|
555 |
- UPDATE_0_CHECK; |
|
556 |
- state = 0; |
|
557 |
- prob = probs + LenCoder; |
|
558 |
- res = DUMMY_MATCH; |
|
559 |
- } |
|
560 |
- else |
|
561 |
- { |
|
562 |
- UPDATE_1_CHECK; |
|
563 |
- res = DUMMY_REP; |
|
564 |
- prob = probs + IsRepG0 + state; |
|
565 |
- IF_BIT_0_CHECK(prob) |
|
566 |
- { |
|
567 |
- UPDATE_0_CHECK; |
|
568 |
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
569 |
- IF_BIT_0_CHECK(prob) |
|
570 |
- { |
|
571 |
- UPDATE_0_CHECK; |
|
572 |
- NORMALIZE_CHECK; |
|
573 |
- return DUMMY_REP; |
|
574 |
- } |
|
575 |
- else |
|
576 |
- { |
|
577 |
- UPDATE_1_CHECK; |
|
578 |
- } |
|
579 |
- } |
|
580 |
- else |
|
581 |
- { |
|
582 |
- UPDATE_1_CHECK; |
|
583 |
- prob = probs + IsRepG1 + state; |
|
584 |
- IF_BIT_0_CHECK(prob) |
|
585 |
- { |
|
586 |
- UPDATE_0_CHECK; |
|
587 |
- } |
|
588 |
- else |
|
589 |
- { |
|
590 |
- UPDATE_1_CHECK; |
|
591 |
- prob = probs + IsRepG2 + state; |
|
592 |
- IF_BIT_0_CHECK(prob) |
|
593 |
- { |
|
594 |
- UPDATE_0_CHECK; |
|
595 |
- } |
|
596 |
- else |
|
597 |
- { |
|
598 |
- UPDATE_1_CHECK; |
|
599 |
- } |
|
600 |
- } |
|
601 |
- } |
|
602 |
- state = kNumStates; |
|
603 |
- prob = probs + RepLenCoder; |
|
604 |
- } |
|
605 |
- { |
|
606 |
- unsigned limit, offset; |
|
607 |
- CLzmaProb *probLen = prob + LenChoice; |
|
608 |
- IF_BIT_0_CHECK(probLen) |
|
609 |
- { |
|
610 |
- UPDATE_0_CHECK; |
|
611 |
- probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
612 |
- offset = 0; |
|
613 |
- limit = 1 << kLenNumLowBits; |
|
614 |
- } |
|
615 |
- else |
|
616 |
- { |
|
617 |
- UPDATE_1_CHECK; |
|
618 |
- probLen = prob + LenChoice2; |
|
619 |
- IF_BIT_0_CHECK(probLen) |
|
620 |
- { |
|
621 |
- UPDATE_0_CHECK; |
|
622 |
- probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
623 |
- offset = kLenNumLowSymbols; |
|
624 |
- limit = 1 << kLenNumMidBits; |
|
625 |
- } |
|
626 |
- else |
|
627 |
- { |
|
628 |
- UPDATE_1_CHECK; |
|
629 |
- probLen = prob + LenHigh; |
|
630 |
- offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
631 |
- limit = 1 << kLenNumHighBits; |
|
632 |
- } |
|
633 |
- } |
|
634 |
- TREE_DECODE_CHECK(probLen, limit, len); |
|
635 |
- len += offset; |
|
636 |
- } |
|
637 |
- |
|
638 |
- if (state < 4) |
|
639 |
- { |
|
640 |
- unsigned posSlot; |
|
641 |
- prob = probs + PosSlot + |
|
642 |
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << |
|
643 |
- kNumPosSlotBits); |
|
644 |
- TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); |
|
645 |
- if (posSlot >= kStartPosModelIndex) |
|
646 |
- { |
|
647 |
- int numDirectBits = ((posSlot >> 1) - 1); |
|
648 |
- |
|
649 |
- /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ |
|
650 |
- |
|
651 |
- if (posSlot < kEndPosModelIndex) |
|
652 |
- { |
|
653 |
- prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; |
|
654 |
- } |
|
655 |
- else |
|
656 |
- { |
|
657 |
- numDirectBits -= kNumAlignBits; |
|
658 |
- do |
|
659 |
- { |
|
660 |
- NORMALIZE_CHECK |
|
661 |
- range >>= 1; |
|
662 |
- code -= range & (((code - range) >> 31) - 1); |
|
663 |
- /* if (code >= range) code -= range; */ |
|
664 |
- } |
|
665 |
- while (--numDirectBits != 0); |
|
666 |
- prob = probs + Align; |
|
667 |
- numDirectBits = kNumAlignBits; |
|
668 |
- } |
|
669 |
- { |
|
670 |
- unsigned i = 1; |
|
671 |
- do |
|
672 |
- { |
|
673 |
- GET_BIT_CHECK(prob + i, i); |
|
674 |
- } |
|
675 |
- while (--numDirectBits != 0); |
|
676 |
- } |
|
677 |
- } |
|
678 |
- } |
|
679 |
- } |
|
680 |
- } |
|
681 |
- NORMALIZE_CHECK; |
|
682 |
- return res; |
|
683 |
-} |
|
684 |
- |
|
685 |
- |
|
686 |
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) |
|
687 |
-{ |
|
688 |
- p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); |
|
689 |
- p->range = 0xFFFFFFFF; |
|
690 |
- p->needFlush = 0; |
|
691 |
-} |
|
692 |
- |
|
693 |
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) |
|
694 |
-{ |
|
695 |
- p->needFlush = 1; |
|
696 |
- p->remainLen = 0; |
|
697 |
- p->tempBufSize = 0; |
|
698 |
- |
|
699 |
- if (initDic) |
|
700 |
- { |
|
701 |
- p->processedPos = 0; |
|
702 |
- p->checkDicSize = 0; |
|
703 |
- p->needInitState = 1; |
|
704 |
- } |
|
705 |
- if (initState) |
|
706 |
- p->needInitState = 1; |
|
707 |
-} |
|
708 |
- |
|
709 |
-void LzmaDec_Init(CLzmaDec *p) |
|
710 |
-{ |
|
711 |
- p->dicPos = 0; |
|
712 |
- LzmaDec_InitDicAndState(p, True, True); |
|
713 |
-} |
|
714 |
- |
|
715 |
-static void LzmaDec_InitStateReal(CLzmaDec *p) |
|
716 |
-{ |
|
717 |
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); |
|
718 |
- UInt32 i; |
|
719 |
- CLzmaProb *probs = p->probs; |
|
720 |
- for (i = 0; i < numProbs; i++) |
|
721 |
- probs[i] = kBitModelTotal >> 1; |
|
722 |
- p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; |
|
723 |
- p->state = 0; |
|
724 |
- p->needInitState = 0; |
|
725 |
-} |
|
726 |
- |
|
727 |
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, |
|
728 |
- ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
729 |
-{ |
|
730 |
- SizeT inSize = *srcLen; |
|
731 |
- (*srcLen) = 0; |
|
732 |
- LzmaDec_WriteRem(p, dicLimit); |
|
733 |
- |
|
734 |
- *status = LZMA_STATUS_NOT_SPECIFIED; |
|
735 |
- |
|
736 |
- while (p->remainLen != kMatchSpecLenStart) |
|
737 |
- { |
|
738 |
- int checkEndMarkNow; |
|
739 |
- |
|
740 |
- if (p->needFlush != 0) |
|
741 |
- { |
|
742 |
- for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) |
|
743 |
- p->tempBuf[p->tempBufSize++] = *src++; |
|
744 |
- if (p->tempBufSize < RC_INIT_SIZE) |
|
745 |
- { |
|
746 |
- *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
747 |
- return SZ_OK; |
|
748 |
- } |
|
749 |
- if (p->tempBuf[0] != 0) |
|
750 |
- return SZ_ERROR_DATA; |
|
751 |
- |
|
752 |
- LzmaDec_InitRc(p, p->tempBuf); |
|
753 |
- p->tempBufSize = 0; |
|
754 |
- } |
|
755 |
- |
|
756 |
- checkEndMarkNow = 0; |
|
757 |
- if (p->dicPos >= dicLimit) |
|
758 |
- { |
|
759 |
- if (p->remainLen == 0 && p->code == 0) |
|
760 |
- { |
|
761 |
- *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; |
|
762 |
- return SZ_OK; |
|
763 |
- } |
|
764 |
- if (finishMode == LZMA_FINISH_ANY) |
|
765 |
- { |
|
766 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
767 |
- return SZ_OK; |
|
768 |
- } |
|
769 |
- if (p->remainLen != 0) |
|
770 |
- { |
|
771 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
772 |
- return SZ_ERROR_DATA; |
|
773 |
- } |
|
774 |
- checkEndMarkNow = 1; |
|
775 |
- } |
|
776 |
- |
|
777 |
- if (p->needInitState) |
|
778 |
- LzmaDec_InitStateReal(p); |
|
779 |
- |
|
780 |
- if (p->tempBufSize == 0) |
|
781 |
- { |
|
782 |
- SizeT processed; |
|
783 |
- const Byte *bufLimit; |
|
784 |
- if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
785 |
- { |
|
786 |
- int dummyRes = LzmaDec_TryDummy(p, src, inSize); |
|
787 |
- if (dummyRes == DUMMY_ERROR) |
|
788 |
- { |
|
789 |
- memcpy(p->tempBuf, src, inSize); |
|
790 |
- p->tempBufSize = (unsigned)inSize; |
|
791 |
- (*srcLen) += inSize; |
|
792 |
- *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
793 |
- return SZ_OK; |
|
794 |
- } |
|
795 |
- if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
796 |
- { |
|
797 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
798 |
- return SZ_ERROR_DATA; |
|
799 |
- } |
|
800 |
- bufLimit = src; |
|
801 |
- } |
|
802 |
- else |
|
803 |
- bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; |
|
804 |
- p->buf = src; |
|
805 |
- if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) |
|
806 |
- return SZ_ERROR_DATA; |
|
807 |
- processed = (SizeT)(p->buf - src); |
|
808 |
- (*srcLen) += processed; |
|
809 |
- src += processed; |
|
810 |
- inSize -= processed; |
|
811 |
- } |
|
812 |
- else |
|
813 |
- { |
|
814 |
- unsigned rem = p->tempBufSize, lookAhead = 0; |
|
815 |
- while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) |
|
816 |
- p->tempBuf[rem++] = src[lookAhead++]; |
|
817 |
- p->tempBufSize = rem; |
|
818 |
- if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
819 |
- { |
|
820 |
- int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); |
|
821 |
- if (dummyRes == DUMMY_ERROR) |
|
822 |
- { |
|
823 |
- (*srcLen) += lookAhead; |
|
824 |
- *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
825 |
- return SZ_OK; |
|
826 |
- } |
|
827 |
- if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
828 |
- { |
|
829 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
830 |
- return SZ_ERROR_DATA; |
|
831 |
- } |
|
832 |
- } |
|
833 |
- p->buf = p->tempBuf; |
|
834 |
- if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) |
|
835 |
- return SZ_ERROR_DATA; |
|
836 |
- lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); |
|
837 |
- (*srcLen) += lookAhead; |
|
838 |
- src += lookAhead; |
|
839 |
- inSize -= lookAhead; |
|
840 |
- p->tempBufSize = 0; |
|
841 |
- } |
|
842 |
- } |
|
843 |
- if (p->code == 0) |
|
844 |
- *status = LZMA_STATUS_FINISHED_WITH_MARK; |
|
845 |
- return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; |
|
846 |
-} |
|
847 |
- |
|
848 |
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
849 |
-{ |
|
850 |
- SizeT outSize = *destLen; |
|
851 |
- SizeT inSize = *srcLen; |
|
852 |
- *srcLen = *destLen = 0; |
|
853 |
- for (;;) |
|
854 |
- { |
|
855 |
- SizeT inSizeCur = inSize, outSizeCur, dicPos; |
|
856 |
- ELzmaFinishMode curFinishMode; |
|
857 |
- SRes res; |
|
858 |
- if (p->dicPos == p->dicBufSize) |
|
859 |
- p->dicPos = 0; |
|
860 |
- dicPos = p->dicPos; |
|
861 |
- if (outSize > p->dicBufSize - dicPos) |
|
862 |
- { |
|
863 |
- outSizeCur = p->dicBufSize; |
|
864 |
- curFinishMode = LZMA_FINISH_ANY; |
|
865 |
- } |
|
866 |
- else |
|
867 |
- { |
|
868 |
- outSizeCur = dicPos + outSize; |
|
869 |
- curFinishMode = finishMode; |
|
870 |
- } |
|
871 |
- |
|
872 |
- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); |
|
873 |
- src += inSizeCur; |
|
874 |
- inSize -= inSizeCur; |
|
875 |
- *srcLen += inSizeCur; |
|
876 |
- outSizeCur = p->dicPos - dicPos; |
|
877 |
- memcpy(dest, p->dic + dicPos, outSizeCur); |
|
878 |
- dest += outSizeCur; |
|
879 |
- outSize -= outSizeCur; |
|
880 |
- *destLen += outSizeCur; |
|
881 |
- if (res != 0) |
|
882 |
- return res; |
|
883 |
- if (outSizeCur == 0 || outSize == 0) |
|
884 |
- return SZ_OK; |
|
885 |
- } |
|
886 |
-} |
|
887 |
- |
|
888 |
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) |
|
889 |
-{ |
|
890 |
- alloc->Free(alloc, p->probs); |
|
891 |
- p->probs = 0; |
|
892 |
-} |
|
893 |
- |
|
894 |
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) |
|
895 |
-{ |
|
896 |
- alloc->Free(alloc, p->dic); |
|
897 |
- p->dic = 0; |
|
898 |
-} |
|
899 |
- |
|
900 |
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) |
|
901 |
-{ |
|
902 |
- LzmaDec_FreeProbs(p, alloc); |
|
903 |
- LzmaDec_FreeDict(p, alloc); |
|
904 |
-} |
|
905 |
- |
|
906 |
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) |
|
907 |
-{ |
|
908 |
- UInt32 dicSize; |
|
909 |
- Byte d; |
|
910 |
- |
|
911 |
- if (size < LZMA_PROPS_SIZE) |
|
912 |
- return SZ_ERROR_UNSUPPORTED; |
|
913 |
- else |
|
914 |
- dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); |
|
915 |
- |
|
916 |
- if (dicSize < LZMA_DIC_MIN) |
|
917 |
- dicSize = LZMA_DIC_MIN; |
|
918 |
- p->dicSize = dicSize; |
|
919 |
- |
|
920 |
- d = data[0]; |
|
921 |
- if (d >= (9 * 5 * 5)) |
|
922 |
- return SZ_ERROR_UNSUPPORTED; |
|
923 |
- |
|
924 |
- p->lc = d % 9; |
|
925 |
- d /= 9; |
|
926 |
- p->pb = d / 5; |
|
927 |
- p->lp = d % 5; |
|
928 |
- |
|
929 |
- return SZ_OK; |
|
930 |
-} |
|
931 |
- |
|
932 |
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) |
|
933 |
-{ |
|
934 |
- UInt32 numProbs = LzmaProps_GetNumProbs(propNew); |
|
935 |
- if (p->probs == 0 || numProbs != p->numProbs) |
|
936 |
- { |
|
937 |
- LzmaDec_FreeProbs(p, alloc); |
|
938 |
- p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); |
|
939 |
- p->numProbs = numProbs; |
|
940 |
- if (p->probs == 0) |
|
941 |
- return SZ_ERROR_MEM; |
|
942 |
- } |
|
943 |
- return SZ_OK; |
|
944 |
-} |
|
945 |
- |
|
946 |
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
947 |
-{ |
|
948 |
- CLzmaProps propNew; |
|
949 |
- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
950 |
- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
951 |
- p->prop = propNew; |
|
952 |
- return SZ_OK; |
|
953 |
-} |
|
954 |
- |
|
955 |
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
956 |
-{ |
|
957 |
- CLzmaProps propNew; |
|
958 |
- SizeT dicBufSize; |
|
959 |
- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
960 |
- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
961 |
- dicBufSize = propNew.dicSize; |
|
962 |
- if (p->dic == 0 || dicBufSize != p->dicBufSize) |
|
963 |
- { |
|
964 |
- LzmaDec_FreeDict(p, alloc); |
|
965 |
- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); |
|
966 |
- if (p->dic == 0) |
|
967 |
- { |
|
968 |
- LzmaDec_FreeProbs(p, alloc); |
|
969 |
- return SZ_ERROR_MEM; |
|
970 |
- } |
|
971 |
- } |
|
972 |
- p->dicBufSize = dicBufSize; |
|
973 |
- p->prop = propNew; |
|
974 |
- return SZ_OK; |
|
975 |
-} |
|
976 |
- |
|
977 |
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
978 |
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
979 |
- ELzmaStatus *status, ISzAlloc *alloc) |
|
980 |
-{ |
|
981 |
- CLzmaDec p; |
|
982 |
- SRes res; |
|
983 |
- SizeT inSize = *srcLen; |
|
984 |
- SizeT outSize = *destLen; |
|
985 |
- *srcLen = *destLen = 0; |
|
986 |
- if (inSize < RC_INIT_SIZE) |
|
987 |
- return SZ_ERROR_INPUT_EOF; |
|
988 |
- |
|
989 |
- LzmaDec_Construct(&p); |
|
990 |
- res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); |
|
991 |
- if (res != 0) |
|
992 |
- return res; |
|
993 |
- p.dic = dest; |
|
994 |
- p.dicBufSize = outSize; |
|
995 |
- |
|
996 |
- LzmaDec_Init(&p); |
|
997 |
- |
|
998 |
- *srcLen = inSize; |
|
999 |
- res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); |
|
1000 |
- |
|
1001 |
- if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) |
|
1002 |
- res = SZ_ERROR_INPUT_EOF; |
|
1003 |
- |
|
1004 |
- (*destLen) = p.dicPos; |
|
1005 |
- LzmaDec_FreeProbs(&p, alloc); |
|
1006 |
- return res; |
|
1007 |
-} |
|
1 |
+/* LzmaDec.c -- LZMA Decoder |
|
2 |
+2008-11-06 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "LzmaDec.h" |
|
5 |
+ |
|
6 |
+#include <string.h> |
|
7 |
+ |
|
8 |
+#define kNumTopBits 24 |
|
9 |
+#define kTopValue ((UInt32)1 << kNumTopBits) |
|
10 |
+ |
|
11 |
+#define kNumBitModelTotalBits 11 |
|
12 |
+#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
13 |
+#define kNumMoveBits 5 |
|
14 |
+ |
|
15 |
+#define RC_INIT_SIZE 5 |
|
16 |
+ |
|
17 |
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } |
|
18 |
+ |
|
19 |
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
20 |
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); |
|
21 |
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); |
|
22 |
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ |
|
23 |
+ { UPDATE_0(p); i = (i + i); A0; } else \ |
|
24 |
+ { UPDATE_1(p); i = (i + i) + 1; A1; } |
|
25 |
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) |
|
26 |
+ |
|
27 |
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } |
|
28 |
+#define TREE_DECODE(probs, limit, i) \ |
|
29 |
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } |
|
30 |
+ |
|
31 |
+/* #define _LZMA_SIZE_OPT */ |
|
32 |
+ |
|
33 |
+#ifdef _LZMA_SIZE_OPT |
|
34 |
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) |
|
35 |
+#else |
|
36 |
+#define TREE_6_DECODE(probs, i) \ |
|
37 |
+ { i = 1; \ |
|
38 |
+ TREE_GET_BIT(probs, i); \ |
|
39 |
+ TREE_GET_BIT(probs, i); \ |
|
40 |
+ TREE_GET_BIT(probs, i); \ |
|
41 |
+ TREE_GET_BIT(probs, i); \ |
|
42 |
+ TREE_GET_BIT(probs, i); \ |
|
43 |
+ TREE_GET_BIT(probs, i); \ |
|
44 |
+ i -= 0x40; } |
|
45 |
+#endif |
|
46 |
+ |
|
47 |
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } |
|
48 |
+ |
|
49 |
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
50 |
+#define UPDATE_0_CHECK range = bound; |
|
51 |
+#define UPDATE_1_CHECK range -= bound; code -= bound; |
|
52 |
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ |
|
53 |
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ |
|
54 |
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } |
|
55 |
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) |
|
56 |
+#define TREE_DECODE_CHECK(probs, limit, i) \ |
|
57 |
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } |
|
58 |
+ |
|
59 |
+ |
|
60 |
+#define kNumPosBitsMax 4 |
|
61 |
+#define kNumPosStatesMax (1 << kNumPosBitsMax) |
|
62 |
+ |
|
63 |
+#define kLenNumLowBits 3 |
|
64 |
+#define kLenNumLowSymbols (1 << kLenNumLowBits) |
|
65 |
+#define kLenNumMidBits 3 |
|
66 |
+#define kLenNumMidSymbols (1 << kLenNumMidBits) |
|
67 |
+#define kLenNumHighBits 8 |
|
68 |
+#define kLenNumHighSymbols (1 << kLenNumHighBits) |
|
69 |
+ |
|
70 |
+#define LenChoice 0 |
|
71 |
+#define LenChoice2 (LenChoice + 1) |
|
72 |
+#define LenLow (LenChoice2 + 1) |
|
73 |
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) |
|
74 |
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) |
|
75 |
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) |
|
76 |
+ |
|
77 |
+ |
|
78 |
+#define kNumStates 12 |
|
79 |
+#define kNumLitStates 7 |
|
80 |
+ |
|
81 |
+#define kStartPosModelIndex 4 |
|
82 |
+#define kEndPosModelIndex 14 |
|
83 |
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) |
|
84 |
+ |
|
85 |
+#define kNumPosSlotBits 6 |
|
86 |
+#define kNumLenToPosStates 4 |
|
87 |
+ |
|
88 |
+#define kNumAlignBits 4 |
|
89 |
+#define kAlignTableSize (1 << kNumAlignBits) |
|
90 |
+ |
|
91 |
+#define kMatchMinLen 2 |
|
92 |
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) |
|
93 |
+ |
|
94 |
+#define IsMatch 0 |
|
95 |
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) |
|
96 |
+#define IsRepG0 (IsRep + kNumStates) |
|
97 |
+#define IsRepG1 (IsRepG0 + kNumStates) |
|
98 |
+#define IsRepG2 (IsRepG1 + kNumStates) |
|
99 |
+#define IsRep0Long (IsRepG2 + kNumStates) |
|
100 |
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) |
|
101 |
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) |
|
102 |
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) |
|
103 |
+#define LenCoder (Align + kAlignTableSize) |
|
104 |
+#define RepLenCoder (LenCoder + kNumLenProbs) |
|
105 |
+#define Literal (RepLenCoder + kNumLenProbs) |
|
106 |
+ |
|
107 |
+#define LZMA_BASE_SIZE 1846 |
|
108 |
+#define LZMA_LIT_SIZE 768 |
|
109 |
+ |
|
110 |
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) |
|
111 |
+ |
|
112 |
+#if Literal != LZMA_BASE_SIZE |
|
113 |
+StopCompilingDueBUG |
|
114 |
+#endif |
|
115 |
+ |
|
116 |
+static const Byte kLiteralNextStates[kNumStates * 2] = |
|
117 |
+{ |
|
118 |
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, |
|
119 |
+ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 |
|
120 |
+}; |
|
121 |
+ |
|
122 |
+#define LZMA_DIC_MIN (1 << 12) |
|
123 |
+ |
|
124 |
+/* First LZMA-symbol is always decoded. |
|
125 |
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization |
|
126 |
+Out: |
|
127 |
+ Result: |
|
128 |
+ SZ_OK - OK |
|
129 |
+ SZ_ERROR_DATA - Error |
|
130 |
+ p->remainLen: |
|
131 |
+ < kMatchSpecLenStart : normal remain |
|
132 |
+ = kMatchSpecLenStart : finished |
|
133 |
+ = kMatchSpecLenStart + 1 : Flush marker |
|
134 |
+ = kMatchSpecLenStart + 2 : State Init Marker |
|
135 |
+*/ |
|
136 |
+ |
|
137 |
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
138 |
+{ |
|
139 |
+ CLzmaProb *probs = p->probs; |
|
140 |
+ |
|
141 |
+ unsigned state = p->state; |
|
142 |
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; |
|
143 |
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; |
|
144 |
+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; |
|
145 |
+ unsigned lc = p->prop.lc; |
|
146 |
+ |
|
147 |
+ Byte *dic = p->dic; |
|
148 |
+ SizeT dicBufSize = p->dicBufSize; |
|
149 |
+ SizeT dicPos = p->dicPos; |
|
150 |
+ |
|
151 |
+ UInt32 processedPos = p->processedPos; |
|
152 |
+ UInt32 checkDicSize = p->checkDicSize; |
|
153 |
+ unsigned len = 0; |
|
154 |
+ |
|
155 |
+ const Byte *buf = p->buf; |
|
156 |
+ UInt32 range = p->range; |
|
157 |
+ UInt32 code = p->code; |
|
158 |
+ |
|
159 |
+ do |
|
160 |
+ { |
|
161 |
+ CLzmaProb *prob; |
|
162 |
+ UInt32 bound; |
|
163 |
+ unsigned ttt; |
|
164 |
+ unsigned posState = processedPos & pbMask; |
|
165 |
+ |
|
166 |
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
167 |
+ IF_BIT_0(prob) |
|
168 |
+ { |
|
169 |
+ unsigned symbol; |
|
170 |
+ UPDATE_0(prob); |
|
171 |
+ prob = probs + Literal; |
|
172 |
+ if (checkDicSize != 0 || processedPos != 0) |
|
173 |
+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + |
|
174 |
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); |
|
175 |
+ |
|
176 |
+ if (state < kNumLitStates) |
|
177 |
+ { |
|
178 |
+ symbol = 1; |
|
179 |
+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); |
|
180 |
+ } |
|
181 |
+ else |
|
182 |
+ { |
|
183 |
+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
184 |
+ unsigned offs = 0x100; |
|
185 |
+ symbol = 1; |
|
186 |
+ do |
|
187 |
+ { |
|
188 |
+ unsigned bit; |
|
189 |
+ CLzmaProb *probLit; |
|
190 |
+ matchByte <<= 1; |
|
191 |
+ bit = (matchByte & offs); |
|
192 |
+ probLit = prob + offs + bit + symbol; |
|
193 |
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) |
|
194 |
+ } |
|
195 |
+ while (symbol < 0x100); |
|
196 |
+ } |
|
197 |
+ dic[dicPos++] = (Byte)symbol; |
|
198 |
+ processedPos++; |
|
199 |
+ |
|
200 |
+ state = kLiteralNextStates[state]; |
|
201 |
+ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ |
|
202 |
+ continue; |
|
203 |
+ } |
|
204 |
+ else |
|
205 |
+ { |
|
206 |
+ UPDATE_1(prob); |
|
207 |
+ prob = probs + IsRep + state; |
|
208 |
+ IF_BIT_0(prob) |
|
209 |
+ { |
|
210 |
+ UPDATE_0(prob); |
|
211 |
+ state += kNumStates; |
|
212 |
+ prob = probs + LenCoder; |
|
213 |
+ } |
|
214 |
+ else |
|
215 |
+ { |
|
216 |
+ UPDATE_1(prob); |
|
217 |
+ if (checkDicSize == 0 && processedPos == 0) |
|
218 |
+ return SZ_ERROR_DATA; |
|
219 |
+ prob = probs + IsRepG0 + state; |
|
220 |
+ IF_BIT_0(prob) |
|
221 |
+ { |
|
222 |
+ UPDATE_0(prob); |
|
223 |
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
224 |
+ IF_BIT_0(prob) |
|
225 |
+ { |
|
226 |
+ UPDATE_0(prob); |
|
227 |
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
228 |
+ dicPos++; |
|
229 |
+ processedPos++; |
|
230 |
+ state = state < kNumLitStates ? 9 : 11; |
|
231 |
+ continue; |
|
232 |
+ } |
|
233 |
+ UPDATE_1(prob); |
|
234 |
+ } |
|
235 |
+ else |
|
236 |
+ { |
|
237 |
+ UInt32 distance; |
|
238 |
+ UPDATE_1(prob); |
|
239 |
+ prob = probs + IsRepG1 + state; |
|
240 |
+ IF_BIT_0(prob) |
|
241 |
+ { |
|
242 |
+ UPDATE_0(prob); |
|
243 |
+ distance = rep1; |
|
244 |
+ } |
|
245 |
+ else |
|
246 |
+ { |
|
247 |
+ UPDATE_1(prob); |
|
248 |
+ prob = probs + IsRepG2 + state; |
|
249 |
+ IF_BIT_0(prob) |
|
250 |
+ { |
|
251 |
+ UPDATE_0(prob); |
|
252 |
+ distance = rep2; |
|
253 |
+ } |
|
254 |
+ else |
|
255 |
+ { |
|
256 |
+ UPDATE_1(prob); |
|
257 |
+ distance = rep3; |
|
258 |
+ rep3 = rep2; |
|
259 |
+ } |
|
260 |
+ rep2 = rep1; |
|
261 |
+ } |
|
262 |
+ rep1 = rep0; |
|
263 |
+ rep0 = distance; |
|
264 |
+ } |
|
265 |
+ state = state < kNumLitStates ? 8 : 11; |
|
266 |
+ prob = probs + RepLenCoder; |
|
267 |
+ } |
|
268 |
+ { |
|
269 |
+ unsigned limit, offset; |
|
270 |
+ CLzmaProb *probLen = prob + LenChoice; |
|
271 |
+ IF_BIT_0(probLen) |
|
272 |
+ { |
|
273 |
+ UPDATE_0(probLen); |
|
274 |
+ probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
275 |
+ offset = 0; |
|
276 |
+ limit = (1 << kLenNumLowBits); |
|
277 |
+ } |
|
278 |
+ else |
|
279 |
+ { |
|
280 |
+ UPDATE_1(probLen); |
|
281 |
+ probLen = prob + LenChoice2; |
|
282 |
+ IF_BIT_0(probLen) |
|
283 |
+ { |
|
284 |
+ UPDATE_0(probLen); |
|
285 |
+ probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
286 |
+ offset = kLenNumLowSymbols; |
|
287 |
+ limit = (1 << kLenNumMidBits); |
|
288 |
+ } |
|
289 |
+ else |
|
290 |
+ { |
|
291 |
+ UPDATE_1(probLen); |
|
292 |
+ probLen = prob + LenHigh; |
|
293 |
+ offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
294 |
+ limit = (1 << kLenNumHighBits); |
|
295 |
+ } |
|
296 |
+ } |
|
297 |
+ TREE_DECODE(probLen, limit, len); |
|
298 |
+ len += offset; |
|
299 |
+ } |
|
300 |
+ |
|
301 |
+ if (state >= kNumStates) |
|
302 |
+ { |
|
303 |
+ UInt32 distance; |
|
304 |
+ prob = probs + PosSlot + |
|
305 |
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); |
|
306 |
+ TREE_6_DECODE(prob, distance); |
|
307 |
+ if (distance >= kStartPosModelIndex) |
|
308 |
+ { |
|
309 |
+ unsigned posSlot = (unsigned)distance; |
|
310 |
+ int numDirectBits = (int)(((distance >> 1) - 1)); |
|
311 |
+ distance = (2 | (distance & 1)); |
|
312 |
+ if (posSlot < kEndPosModelIndex) |
|
313 |
+ { |
|
314 |
+ distance <<= numDirectBits; |
|
315 |
+ prob = probs + SpecPos + distance - posSlot - 1; |
|
316 |
+ { |
|
317 |
+ UInt32 mask = 1; |
|
318 |
+ unsigned i = 1; |
|
319 |
+ do |
|
320 |
+ { |
|
321 |
+ GET_BIT2(prob + i, i, ; , distance |= mask); |
|
322 |
+ mask <<= 1; |
|
323 |
+ } |
|
324 |
+ while (--numDirectBits != 0); |
|
325 |
+ } |
|
326 |
+ } |
|
327 |
+ else |
|
328 |
+ { |
|
329 |
+ numDirectBits -= kNumAlignBits; |
|
330 |
+ do |
|
331 |
+ { |
|
332 |
+ NORMALIZE |
|
333 |
+ range >>= 1; |
|
334 |
+ |
|
335 |
+ { |
|
336 |
+ UInt32 t; |
|
337 |
+ code -= range; |
|
338 |
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ |
|
339 |
+ distance = (distance << 1) + (t + 1); |
|
340 |
+ code += range & t; |
|
341 |
+ } |
|
342 |
+ /* |
|
343 |
+ distance <<= 1; |
|
344 |
+ if (code >= range) |
|
345 |
+ { |
|
346 |
+ code -= range; |
|
347 |
+ distance |= 1; |
|
348 |
+ } |
|
349 |
+ */ |
|
350 |
+ } |
|
351 |
+ while (--numDirectBits != 0); |
|
352 |
+ prob = probs + Align; |
|
353 |
+ distance <<= kNumAlignBits; |
|
354 |
+ { |
|
355 |
+ unsigned i = 1; |
|
356 |
+ GET_BIT2(prob + i, i, ; , distance |= 1); |
|
357 |
+ GET_BIT2(prob + i, i, ; , distance |= 2); |
|
358 |
+ GET_BIT2(prob + i, i, ; , distance |= 4); |
|
359 |
+ GET_BIT2(prob + i, i, ; , distance |= 8); |
|
360 |
+ } |
|
361 |
+ if (distance == (UInt32)0xFFFFFFFF) |
|
362 |
+ { |
|
363 |
+ len += kMatchSpecLenStart; |
|
364 |
+ state -= kNumStates; |
|
365 |
+ break; |
|
366 |
+ } |
|
367 |
+ } |
|
368 |
+ } |
|
369 |
+ rep3 = rep2; |
|
370 |
+ rep2 = rep1; |
|
371 |
+ rep1 = rep0; |
|
372 |
+ rep0 = distance + 1; |
|
373 |
+ if (checkDicSize == 0) |
|
374 |
+ { |
|
375 |
+ if (distance >= processedPos) |
|
376 |
+ return SZ_ERROR_DATA; |
|
377 |
+ } |
|
378 |
+ else if (distance >= checkDicSize) |
|
379 |
+ return SZ_ERROR_DATA; |
|
380 |
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; |
|
381 |
+ /* state = kLiteralNextStates[state]; */ |
|
382 |
+ } |
|
383 |
+ |
|
384 |
+ len += kMatchMinLen; |
|
385 |
+ |
|
386 |
+ if (limit == dicPos) |
|
387 |
+ return SZ_ERROR_DATA; |
|
388 |
+ { |
|
389 |
+ SizeT rem = limit - dicPos; |
|
390 |
+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); |
|
391 |
+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); |
|
392 |
+ |
|
393 |
+ processedPos += curLen; |
|
394 |
+ |
|
395 |
+ len -= curLen; |
|
396 |
+ if (pos + curLen <= dicBufSize) |
|
397 |
+ { |
|
398 |
+ Byte *dest = dic + dicPos; |
|
399 |
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; |
|
400 |
+ const Byte *lim = dest + curLen; |
|
401 |
+ dicPos += curLen; |
|
402 |
+ do |
|
403 |
+ *(dest) = (Byte)*(dest + src); |
|
404 |
+ while (++dest != lim); |
|
405 |
+ } |
|
406 |
+ else |
|
407 |
+ { |
|
408 |
+ do |
|
409 |
+ { |
|
410 |
+ dic[dicPos++] = dic[pos]; |
|
411 |
+ if (++pos == dicBufSize) |
|
412 |
+ pos = 0; |
|
413 |
+ } |
|
414 |
+ while (--curLen != 0); |
|
415 |
+ } |
|
416 |
+ } |
|
417 |
+ } |
|
418 |
+ } |
|
419 |
+ while (dicPos < limit && buf < bufLimit); |
|
420 |
+ NORMALIZE; |
|
421 |
+ p->buf = buf; |
|
422 |
+ p->range = range; |
|
423 |
+ p->code = code; |
|
424 |
+ p->remainLen = len; |
|
425 |
+ p->dicPos = dicPos; |
|
426 |
+ p->processedPos = processedPos; |
|
427 |
+ p->reps[0] = rep0; |
|
428 |
+ p->reps[1] = rep1; |
|
429 |
+ p->reps[2] = rep2; |
|
430 |
+ p->reps[3] = rep3; |
|
431 |
+ p->state = state; |
|
432 |
+ |
|
433 |
+ return SZ_OK; |
|
434 |
+} |
|
435 |
+ |
|
436 |
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) |
|
437 |
+{ |
|
438 |
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) |
|
439 |
+ { |
|
440 |
+ Byte *dic = p->dic; |
|
441 |
+ SizeT dicPos = p->dicPos; |
|
442 |
+ SizeT dicBufSize = p->dicBufSize; |
|
443 |
+ unsigned len = p->remainLen; |
|
444 |
+ UInt32 rep0 = p->reps[0]; |
|
445 |
+ if (limit - dicPos < len) |
|
446 |
+ len = (unsigned)(limit - dicPos); |
|
447 |
+ |
|
448 |
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) |
|
449 |
+ p->checkDicSize = p->prop.dicSize; |
|
450 |
+ |
|
451 |
+ p->processedPos += len; |
|
452 |
+ p->remainLen -= len; |
|
453 |
+ while (len-- != 0) |
|
454 |
+ { |
|
455 |
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
456 |
+ dicPos++; |
|
457 |
+ } |
|
458 |
+ p->dicPos = dicPos; |
|
459 |
+ } |
|
460 |
+} |
|
461 |
+ |
|
462 |
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
463 |
+{ |
|
464 |
+ do |
|
465 |
+ { |
|
466 |
+ SizeT limit2 = limit; |
|
467 |
+ if (p->checkDicSize == 0) |
|
468 |
+ { |
|
469 |
+ UInt32 rem = p->prop.dicSize - p->processedPos; |
|
470 |
+ if (limit - p->dicPos > rem) |
|
471 |
+ limit2 = p->dicPos + rem; |
|
472 |
+ } |
|
473 |
+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); |
|
474 |
+ if (p->processedPos >= p->prop.dicSize) |
|
475 |
+ p->checkDicSize = p->prop.dicSize; |
|
476 |
+ LzmaDec_WriteRem(p, limit); |
|
477 |
+ } |
|
478 |
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); |
|
479 |
+ |
|
480 |
+ if (p->remainLen > kMatchSpecLenStart) |
|
481 |
+ { |
|
482 |
+ p->remainLen = kMatchSpecLenStart; |
|
483 |
+ } |
|
484 |
+ return 0; |
|
485 |
+} |
|
486 |
+ |
|
487 |
+typedef enum |
|
488 |
+{ |
|
489 |
+ DUMMY_ERROR, /* unexpected end of input stream */ |
|
490 |
+ DUMMY_LIT, |
|
491 |
+ DUMMY_MATCH, |
|
492 |
+ DUMMY_REP |
|
493 |
+} ELzmaDummy; |
|
494 |
+ |
|
495 |
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) |
|
496 |
+{ |
|
497 |
+ UInt32 range = p->range; |
|
498 |
+ UInt32 code = p->code; |
|
499 |
+ const Byte *bufLimit = buf + inSize; |
|
500 |
+ CLzmaProb *probs = p->probs; |
|
501 |
+ unsigned state = p->state; |
|
502 |
+ ELzmaDummy res; |
|
503 |
+ |
|
504 |
+ { |
|
505 |
+ CLzmaProb *prob; |
|
506 |
+ UInt32 bound; |
|
507 |
+ unsigned ttt; |
|
508 |
+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); |
|
509 |
+ |
|
510 |
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
511 |
+ IF_BIT_0_CHECK(prob) |
|
512 |
+ { |
|
513 |
+ UPDATE_0_CHECK |
|
514 |
+ |
|
515 |
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ |
|
516 |
+ |
|
517 |
+ prob = probs + Literal; |
|
518 |
+ if (p->checkDicSize != 0 || p->processedPos != 0) |
|
519 |
+ prob += (LZMA_LIT_SIZE * |
|
520 |
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + |
|
521 |
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); |
|
522 |
+ |
|
523 |
+ if (state < kNumLitStates) |
|
524 |
+ { |
|
525 |
+ unsigned symbol = 1; |
|
526 |
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); |
|
527 |
+ } |
|
528 |
+ else |
|
529 |
+ { |
|
530 |
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + |
|
531 |
+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; |
|
532 |
+ unsigned offs = 0x100; |
|
533 |
+ unsigned symbol = 1; |
|
534 |
+ do |
|
535 |
+ { |
|
536 |
+ unsigned bit; |
|
537 |
+ CLzmaProb *probLit; |
|
538 |
+ matchByte <<= 1; |
|
539 |
+ bit = (matchByte & offs); |
|
540 |
+ probLit = prob + offs + bit + symbol; |
|
541 |
+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) |
|
542 |
+ } |
|
543 |
+ while (symbol < 0x100); |
|
544 |
+ } |
|
545 |
+ res = DUMMY_LIT; |
|
546 |
+ } |
|
547 |
+ else |
|
548 |
+ { |
|
549 |
+ unsigned len; |
|
550 |
+ UPDATE_1_CHECK; |
|
551 |
+ |
|
552 |
+ prob = probs + IsRep + state; |
|
553 |
+ IF_BIT_0_CHECK(prob) |
|
554 |
+ { |
|
555 |
+ UPDATE_0_CHECK; |
|
556 |
+ state = 0; |
|
557 |
+ prob = probs + LenCoder; |
|
558 |
+ res = DUMMY_MATCH; |
|
559 |
+ } |
|
560 |
+ else |
|
561 |
+ { |
|
562 |
+ UPDATE_1_CHECK; |
|
563 |
+ res = DUMMY_REP; |
|
564 |
+ prob = probs + IsRepG0 + state; |
|
565 |
+ IF_BIT_0_CHECK(prob) |
|
566 |
+ { |
|
567 |
+ UPDATE_0_CHECK; |
|
568 |
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
569 |
+ IF_BIT_0_CHECK(prob) |
|
570 |
+ { |
|
571 |
+ UPDATE_0_CHECK; |
|
572 |
+ NORMALIZE_CHECK; |
|
573 |
+ return DUMMY_REP; |
|
574 |
+ } |
|
575 |
+ else |
|
576 |
+ { |
|
577 |
+ UPDATE_1_CHECK; |
|
578 |
+ } |
|
579 |
+ } |
|
580 |
+ else |
|
581 |
+ { |
|
582 |
+ UPDATE_1_CHECK; |
|
583 |
+ prob = probs + IsRepG1 + state; |
|
584 |
+ IF_BIT_0_CHECK(prob) |
|
585 |
+ { |
|
586 |
+ UPDATE_0_CHECK; |
|
587 |
+ } |
|
588 |
+ else |
|
589 |
+ { |
|
590 |
+ UPDATE_1_CHECK; |
|
591 |
+ prob = probs + IsRepG2 + state; |
|
592 |
+ IF_BIT_0_CHECK(prob) |
|
593 |
+ { |
|
594 |
+ UPDATE_0_CHECK; |
|
595 |
+ } |
|
596 |
+ else |
|
597 |
+ { |
|
598 |
+ UPDATE_1_CHECK; |
|
599 |
+ } |
|
600 |
+ } |
|
601 |
+ } |
|
602 |
+ state = kNumStates; |
|
603 |
+ prob = probs + RepLenCoder; |
|
604 |
+ } |
|
605 |
+ { |
|
606 |
+ unsigned limit, offset; |
|
607 |
+ CLzmaProb *probLen = prob + LenChoice; |
|
608 |
+ IF_BIT_0_CHECK(probLen) |
|
609 |
+ { |
|
610 |
+ UPDATE_0_CHECK; |
|
611 |
+ probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
612 |
+ offset = 0; |
|
613 |
+ limit = 1 << kLenNumLowBits; |
|
614 |
+ } |
|
615 |
+ else |
|
616 |
+ { |
|
617 |
+ UPDATE_1_CHECK; |
|
618 |
+ probLen = prob + LenChoice2; |
|
619 |
+ IF_BIT_0_CHECK(probLen) |
|
620 |
+ { |
|
621 |
+ UPDATE_0_CHECK; |
|
622 |
+ probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
623 |
+ offset = kLenNumLowSymbols; |
|
624 |
+ limit = 1 << kLenNumMidBits; |
|
625 |
+ } |
|
626 |
+ else |
|
627 |
+ { |
|
628 |
+ UPDATE_1_CHECK; |
|
629 |
+ probLen = prob + LenHigh; |
|
630 |
+ offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
631 |
+ limit = 1 << kLenNumHighBits; |
|
632 |
+ } |
|
633 |
+ } |
|
634 |
+ TREE_DECODE_CHECK(probLen, limit, len); |
|
635 |
+ len += offset; |
|
636 |
+ } |
|
637 |
+ |
|
638 |
+ if (state < 4) |
|
639 |
+ { |
|
640 |
+ unsigned posSlot; |
|
641 |
+ prob = probs + PosSlot + |
|
642 |
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << |
|
643 |
+ kNumPosSlotBits); |
|
644 |
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); |
|
645 |
+ if (posSlot >= kStartPosModelIndex) |
|
646 |
+ { |
|
647 |
+ int numDirectBits = ((posSlot >> 1) - 1); |
|
648 |
+ |
|
649 |
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ |
|
650 |
+ |
|
651 |
+ if (posSlot < kEndPosModelIndex) |
|
652 |
+ { |
|
653 |
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; |
|
654 |
+ } |
|
655 |
+ else |
|
656 |
+ { |
|
657 |
+ numDirectBits -= kNumAlignBits; |
|
658 |
+ do |
|
659 |
+ { |
|
660 |
+ NORMALIZE_CHECK |
|
661 |
+ range >>= 1; |
|
662 |
+ code -= range & (((code - range) >> 31) - 1); |
|
663 |
+ /* if (code >= range) code -= range; */ |
|
664 |
+ } |
|
665 |
+ while (--numDirectBits != 0); |
|
666 |
+ prob = probs + Align; |
|
667 |
+ numDirectBits = kNumAlignBits; |
|
668 |
+ } |
|
669 |
+ { |
|
670 |
+ unsigned i = 1; |
|
671 |
+ do |
|
672 |
+ { |
|
673 |
+ GET_BIT_CHECK(prob + i, i); |
|
674 |
+ } |
|
675 |
+ while (--numDirectBits != 0); |
|
676 |
+ } |
|
677 |
+ } |
|
678 |
+ } |
|
679 |
+ } |
|
680 |
+ } |
|
681 |
+ NORMALIZE_CHECK; |
|
682 |
+ return res; |
|
683 |
+} |
|
684 |
+ |
|
685 |
+ |
|
686 |
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) |
|
687 |
+{ |
|
688 |
+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); |
|
689 |
+ p->range = 0xFFFFFFFF; |
|
690 |
+ p->needFlush = 0; |
|
691 |
+} |
|
692 |
+ |
|
693 |
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) |
|
694 |
+{ |
|
695 |
+ p->needFlush = 1; |
|
696 |
+ p->remainLen = 0; |
|
697 |
+ p->tempBufSize = 0; |
|
698 |
+ |
|
699 |
+ if (initDic) |
|
700 |
+ { |
|
701 |
+ p->processedPos = 0; |
|
702 |
+ p->checkDicSize = 0; |
|
703 |
+ p->needInitState = 1; |
|
704 |
+ } |
|
705 |
+ if (initState) |
|
706 |
+ p->needInitState = 1; |
|
707 |
+} |
|
708 |
+ |
|
709 |
+void LzmaDec_Init(CLzmaDec *p) |
|
710 |
+{ |
|
711 |
+ p->dicPos = 0; |
|
712 |
+ LzmaDec_InitDicAndState(p, True, True); |
|
713 |
+} |
|
714 |
+ |
|
715 |
+static void LzmaDec_InitStateReal(CLzmaDec *p) |
|
716 |
+{ |
|
717 |
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); |
|
718 |
+ UInt32 i; |
|
719 |
+ CLzmaProb *probs = p->probs; |
|
720 |
+ for (i = 0; i < numProbs; i++) |
|
721 |
+ probs[i] = kBitModelTotal >> 1; |
|
722 |
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; |
|
723 |
+ p->state = 0; |
|
724 |
+ p->needInitState = 0; |
|
725 |
+} |
|
726 |
+ |
|
727 |
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, |
|
728 |
+ ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
729 |
+{ |
|
730 |
+ SizeT inSize = *srcLen; |
|
731 |
+ (*srcLen) = 0; |
|
732 |
+ LzmaDec_WriteRem(p, dicLimit); |
|
733 |
+ |
|
734 |
+ *status = LZMA_STATUS_NOT_SPECIFIED; |
|
735 |
+ |
|
736 |
+ while (p->remainLen != kMatchSpecLenStart) |
|
737 |
+ { |
|
738 |
+ int checkEndMarkNow; |
|
739 |
+ |
|
740 |
+ if (p->needFlush != 0) |
|
741 |
+ { |
|
742 |
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) |
|
743 |
+ p->tempBuf[p->tempBufSize++] = *src++; |
|
744 |
+ if (p->tempBufSize < RC_INIT_SIZE) |
|
745 |
+ { |
|
746 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
747 |
+ return SZ_OK; |
|
748 |
+ } |
|
749 |
+ if (p->tempBuf[0] != 0) |
|
750 |
+ return SZ_ERROR_DATA; |
|
751 |
+ |
|
752 |
+ LzmaDec_InitRc(p, p->tempBuf); |
|
753 |
+ p->tempBufSize = 0; |
|
754 |
+ } |
|
755 |
+ |
|
756 |
+ checkEndMarkNow = 0; |
|
757 |
+ if (p->dicPos >= dicLimit) |
|
758 |
+ { |
|
759 |
+ if (p->remainLen == 0 && p->code == 0) |
|
760 |
+ { |
|
761 |
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; |
|
762 |
+ return SZ_OK; |
|
763 |
+ } |
|
764 |
+ if (finishMode == LZMA_FINISH_ANY) |
|
765 |
+ { |
|
766 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
767 |
+ return SZ_OK; |
|
768 |
+ } |
|
769 |
+ if (p->remainLen != 0) |
|
770 |
+ { |
|
771 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
772 |
+ return SZ_ERROR_DATA; |
|
773 |
+ } |
|
774 |
+ checkEndMarkNow = 1; |
|
775 |
+ } |
|
776 |
+ |
|
777 |
+ if (p->needInitState) |
|
778 |
+ LzmaDec_InitStateReal(p); |
|
779 |
+ |
|
780 |
+ if (p->tempBufSize == 0) |
|
781 |
+ { |
|
782 |
+ SizeT processed; |
|
783 |
+ const Byte *bufLimit; |
|
784 |
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
785 |
+ { |
|
786 |
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); |
|
787 |
+ if (dummyRes == DUMMY_ERROR) |
|
788 |
+ { |
|
789 |
+ memcpy(p->tempBuf, src, inSize); |
|
790 |
+ p->tempBufSize = (unsigned)inSize; |
|
791 |
+ (*srcLen) += inSize; |
|
792 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
793 |
+ return SZ_OK; |
|
794 |
+ } |
|
795 |
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
796 |
+ { |
|
797 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
798 |
+ return SZ_ERROR_DATA; |
|
799 |
+ } |
|
800 |
+ bufLimit = src; |
|
801 |
+ } |
|
802 |
+ else |
|
803 |
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; |
|
804 |
+ p->buf = src; |
|
805 |
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) |
|
806 |
+ return SZ_ERROR_DATA; |
|
807 |
+ processed = (SizeT)(p->buf - src); |
|
808 |
+ (*srcLen) += processed; |
|
809 |
+ src += processed; |
|
810 |
+ inSize -= processed; |
|
811 |
+ } |
|
812 |
+ else |
|
813 |
+ { |
|
814 |
+ unsigned rem = p->tempBufSize, lookAhead = 0; |
|
815 |
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) |
|
816 |
+ p->tempBuf[rem++] = src[lookAhead++]; |
|
817 |
+ p->tempBufSize = rem; |
|
818 |
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
819 |
+ { |
|
820 |
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); |
|
821 |
+ if (dummyRes == DUMMY_ERROR) |
|
822 |
+ { |
|
823 |
+ (*srcLen) += lookAhead; |
|
824 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
825 |
+ return SZ_OK; |
|
826 |
+ } |
|
827 |
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
828 |
+ { |
|
829 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
830 |
+ return SZ_ERROR_DATA; |
|
831 |
+ } |
|
832 |
+ } |
|
833 |
+ p->buf = p->tempBuf; |
|
834 |
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) |
|
835 |
+ return SZ_ERROR_DATA; |
|
836 |
+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); |
|
837 |
+ (*srcLen) += lookAhead; |
|
838 |
+ src += lookAhead; |
|
839 |
+ inSize -= lookAhead; |
|
840 |
+ p->tempBufSize = 0; |
|
841 |
+ } |
|
842 |
+ } |
|
843 |
+ if (p->code == 0) |
|
844 |
+ *status = LZMA_STATUS_FINISHED_WITH_MARK; |
|
845 |
+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; |
|
846 |
+} |
|
847 |
+ |
|
848 |
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
849 |
+{ |
|
850 |
+ SizeT outSize = *destLen; |
|
851 |
+ SizeT inSize = *srcLen; |
|
852 |
+ *srcLen = *destLen = 0; |
|
853 |
+ for (;;) |
|
854 |
+ { |
|
855 |
+ SizeT inSizeCur = inSize, outSizeCur, dicPos; |
|
856 |
+ ELzmaFinishMode curFinishMode; |
|
857 |
+ SRes res; |
|
858 |
+ if (p->dicPos == p->dicBufSize) |
|
859 |
+ p->dicPos = 0; |
|
860 |
+ dicPos = p->dicPos; |
|
861 |
+ if (outSize > p->dicBufSize - dicPos) |
|
862 |
+ { |
|
863 |
+ outSizeCur = p->dicBufSize; |
|
864 |
+ curFinishMode = LZMA_FINISH_ANY; |
|
865 |
+ } |
|
866 |
+ else |
|
867 |
+ { |
|
868 |
+ outSizeCur = dicPos + outSize; |
|
869 |
+ curFinishMode = finishMode; |
|
870 |
+ } |
|
871 |
+ |
|
872 |
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); |
|
873 |
+ src += inSizeCur; |
|
874 |
+ inSize -= inSizeCur; |
|
875 |
+ *srcLen += inSizeCur; |
|
876 |
+ outSizeCur = p->dicPos - dicPos; |
|
877 |
+ memcpy(dest, p->dic + dicPos, outSizeCur); |
|
878 |
+ dest += outSizeCur; |
|
879 |
+ outSize -= outSizeCur; |
|
880 |
+ *destLen += outSizeCur; |
|
881 |
+ if (res != 0) |
|
882 |
+ return res; |
|
883 |
+ if (outSizeCur == 0 || outSize == 0) |
|
884 |
+ return SZ_OK; |
|
885 |
+ } |
|
886 |
+} |
|
887 |
+ |
|
888 |
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) |
|
889 |
+{ |
|
890 |
+ alloc->Free(alloc, p->probs); |
|
891 |
+ p->probs = 0; |
|
892 |
+} |
|
893 |
+ |
|
894 |
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) |
|
895 |
+{ |
|
896 |
+ alloc->Free(alloc, p->dic); |
|
897 |
+ p->dic = 0; |
|
898 |
+} |
|
899 |
+ |
|
900 |
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) |
|
901 |
+{ |
|
902 |
+ LzmaDec_FreeProbs(p, alloc); |
|
903 |
+ LzmaDec_FreeDict(p, alloc); |
|
904 |
+} |
|
905 |
+ |
|
906 |
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) |
|
907 |
+{ |
|
908 |
+ UInt32 dicSize; |
|
909 |
+ Byte d; |
|
910 |
+ |
|
911 |
+ if (size < LZMA_PROPS_SIZE) |
|
912 |
+ return SZ_ERROR_UNSUPPORTED; |
|
913 |
+ else |
|
914 |
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); |
|
915 |
+ |
|
916 |
+ if (dicSize < LZMA_DIC_MIN) |
|
917 |
+ dicSize = LZMA_DIC_MIN; |
|
918 |
+ p->dicSize = dicSize; |
|
919 |
+ |
|
920 |
+ d = data[0]; |
|
921 |
+ if (d >= (9 * 5 * 5)) |
|
922 |
+ return SZ_ERROR_UNSUPPORTED; |
|
923 |
+ |
|
924 |
+ p->lc = d % 9; |
|
925 |
+ d /= 9; |
|
926 |
+ p->pb = d / 5; |
|
927 |
+ p->lp = d % 5; |
|
928 |
+ |
|
929 |
+ return SZ_OK; |
|
930 |
+} |
|
931 |
+ |
|
932 |
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) |
|
933 |
+{ |
|
934 |
+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); |
|
935 |
+ if (p->probs == 0 || numProbs != p->numProbs) |
|
936 |
+ { |
|
937 |
+ LzmaDec_FreeProbs(p, alloc); |
|
938 |
+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); |
|
939 |
+ p->numProbs = numProbs; |
|
940 |
+ if (p->probs == 0) |
|
941 |
+ return SZ_ERROR_MEM; |
|
942 |
+ } |
|
943 |
+ return SZ_OK; |
|
944 |
+} |
|
945 |
+ |
|
946 |
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
947 |
+{ |
|
948 |
+ CLzmaProps propNew; |
|
949 |
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
950 |
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
951 |
+ p->prop = propNew; |
|
952 |
+ return SZ_OK; |
|
953 |
+} |
|
954 |
+ |
|
955 |
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
956 |
+{ |
|
957 |
+ CLzmaProps propNew; |
|
958 |
+ SizeT dicBufSize; |
|
959 |
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
960 |
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
961 |
+ dicBufSize = propNew.dicSize; |
|
962 |
+ if (p->dic == 0 || dicBufSize != p->dicBufSize) |
|
963 |
+ { |
|
964 |
+ LzmaDec_FreeDict(p, alloc); |
|
965 |
+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); |
|
966 |
+ if (p->dic == 0) |
|
967 |
+ { |
|
968 |
+ LzmaDec_FreeProbs(p, alloc); |
|
969 |
+ return SZ_ERROR_MEM; |
|
970 |
+ } |
|
971 |
+ } |
|
972 |
+ p->dicBufSize = dicBufSize; |
|
973 |
+ p->prop = propNew; |
|
974 |
+ return SZ_OK; |
|
975 |
+} |
|
976 |
+ |
|
977 |
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
978 |
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
979 |
+ ELzmaStatus *status, ISzAlloc *alloc) |
|
980 |
+{ |
|
981 |
+ CLzmaDec p; |
|
982 |
+ SRes res; |
|
983 |
+ SizeT inSize = *srcLen; |
|
984 |
+ SizeT outSize = *destLen; |
|
985 |
+ *srcLen = *destLen = 0; |
|
986 |
+ if (inSize < RC_INIT_SIZE) |
|
987 |
+ return SZ_ERROR_INPUT_EOF; |
|
988 |
+ |
|
989 |
+ LzmaDec_Construct(&p); |
|
990 |
+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); |
|
991 |
+ if (res != 0) |
|
992 |
+ return res; |
|
993 |
+ p.dic = dest; |
|
994 |
+ p.dicBufSize = outSize; |
|
995 |
+ |
|
996 |
+ LzmaDec_Init(&p); |
|
997 |
+ |
|
998 |
+ *srcLen = inSize; |
|
999 |
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); |
|
1000 |
+ |
|
1001 |
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) |
|
1002 |
+ res = SZ_ERROR_INPUT_EOF; |
|
1003 |
+ |
|
1004 |
+ (*destLen) = p.dicPos; |
|
1005 |
+ LzmaDec_FreeProbs(&p, alloc); |
|
1006 |
+ return res; |
|
1007 |
+} |
... | ... |
@@ -1,223 +1,223 @@ |
1 |
-/* LzmaDec.h -- LZMA Decoder |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __LZMADEC_H |
|
5 |
-#define __LZMADEC_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-/* #define _LZMA_PROB32 */ |
|
10 |
-/* _LZMA_PROB32 can increase the speed on some CPUs, |
|
11 |
- but memory usage for CLzmaDec::probs will be doubled in that case */ |
|
12 |
- |
|
13 |
-#ifdef _LZMA_PROB32 |
|
14 |
-#define CLzmaProb UInt32 |
|
15 |
-#else |
|
16 |
-#define CLzmaProb UInt16 |
|
17 |
-#endif |
|
18 |
- |
|
19 |
- |
|
20 |
-/* ---------- LZMA Properties ---------- */ |
|
21 |
- |
|
22 |
-#define LZMA_PROPS_SIZE 5 |
|
23 |
- |
|
24 |
-typedef struct _CLzmaProps |
|
25 |
-{ |
|
26 |
- unsigned lc, lp, pb; |
|
27 |
- UInt32 dicSize; |
|
28 |
-} CLzmaProps; |
|
29 |
- |
|
30 |
-/* LzmaProps_Decode - decodes properties |
|
31 |
-Returns: |
|
32 |
- SZ_OK |
|
33 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
34 |
-*/ |
|
35 |
- |
|
36 |
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); |
|
37 |
- |
|
38 |
- |
|
39 |
-/* ---------- LZMA Decoder state ---------- */ |
|
40 |
- |
|
41 |
-/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. |
|
42 |
- Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ |
|
43 |
- |
|
44 |
-#define LZMA_REQUIRED_INPUT_MAX 20 |
|
45 |
- |
|
46 |
-typedef struct |
|
47 |
-{ |
|
48 |
- CLzmaProps prop; |
|
49 |
- CLzmaProb *probs; |
|
50 |
- Byte *dic; |
|
51 |
- const Byte *buf; |
|
52 |
- UInt32 range, code; |
|
53 |
- SizeT dicPos; |
|
54 |
- SizeT dicBufSize; |
|
55 |
- UInt32 processedPos; |
|
56 |
- UInt32 checkDicSize; |
|
57 |
- unsigned state; |
|
58 |
- UInt32 reps[4]; |
|
59 |
- unsigned remainLen; |
|
60 |
- int needFlush; |
|
61 |
- int needInitState; |
|
62 |
- UInt32 numProbs; |
|
63 |
- unsigned tempBufSize; |
|
64 |
- Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; |
|
65 |
-} CLzmaDec; |
|
66 |
- |
|
67 |
-#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } |
|
68 |
- |
|
69 |
-void LzmaDec_Init(CLzmaDec *p); |
|
70 |
- |
|
71 |
-/* There are two types of LZMA streams: |
|
72 |
- 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. |
|
73 |
- 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ |
|
74 |
- |
|
75 |
-typedef enum |
|
76 |
-{ |
|
77 |
- LZMA_FINISH_ANY, /* finish at any point */ |
|
78 |
- LZMA_FINISH_END /* block must be finished at the end */ |
|
79 |
-} ELzmaFinishMode; |
|
80 |
- |
|
81 |
-/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! |
|
82 |
- |
|
83 |
- You must use LZMA_FINISH_END, when you know that current output buffer |
|
84 |
- covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. |
|
85 |
- |
|
86 |
- If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, |
|
87 |
- and output value of destLen will be less than output buffer size limit. |
|
88 |
- You can check status result also. |
|
89 |
- |
|
90 |
- You can use multiple checks to test data integrity after full decompression: |
|
91 |
- 1) Check Result and "status" variable. |
|
92 |
- 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. |
|
93 |
- 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. |
|
94 |
- You must use correct finish mode in that case. */ |
|
95 |
- |
|
96 |
-typedef enum |
|
97 |
-{ |
|
98 |
- LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ |
|
99 |
- LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ |
|
100 |
- LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ |
|
101 |
- LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ |
|
102 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ |
|
103 |
-} ELzmaStatus; |
|
104 |
- |
|
105 |
-/* ELzmaStatus is used only as output value for function call */ |
|
106 |
- |
|
107 |
- |
|
108 |
-/* ---------- Interfaces ---------- */ |
|
109 |
- |
|
110 |
-/* There are 3 levels of interfaces: |
|
111 |
- 1) Dictionary Interface |
|
112 |
- 2) Buffer Interface |
|
113 |
- 3) One Call Interface |
|
114 |
- You can select any of these interfaces, but don't mix functions from different |
|
115 |
- groups for same object. */ |
|
116 |
- |
|
117 |
- |
|
118 |
-/* There are two variants to allocate state for Dictionary Interface: |
|
119 |
- 1) LzmaDec_Allocate / LzmaDec_Free |
|
120 |
- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs |
|
121 |
- You can use variant 2, if you set dictionary buffer manually. |
|
122 |
- For Buffer Interface you must always use variant 1. |
|
123 |
- |
|
124 |
-LzmaDec_Allocate* can return: |
|
125 |
- SZ_OK |
|
126 |
- SZ_ERROR_MEM - Memory allocation error |
|
127 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
128 |
-*/ |
|
129 |
- |
|
130 |
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); |
|
131 |
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); |
|
132 |
- |
|
133 |
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); |
|
134 |
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); |
|
135 |
- |
|
136 |
-/* ---------- Dictionary Interface ---------- */ |
|
137 |
- |
|
138 |
-/* You can use it, if you want to eliminate the overhead for data copying from |
|
139 |
- dictionary to some other external buffer. |
|
140 |
- You must work with CLzmaDec variables directly in this interface. |
|
141 |
- |
|
142 |
- STEPS: |
|
143 |
- LzmaDec_Constr() |
|
144 |
- LzmaDec_Allocate() |
|
145 |
- for (each new stream) |
|
146 |
- { |
|
147 |
- LzmaDec_Init() |
|
148 |
- while (it needs more decompression) |
|
149 |
- { |
|
150 |
- LzmaDec_DecodeToDic() |
|
151 |
- use data from CLzmaDec::dic and update CLzmaDec::dicPos |
|
152 |
- } |
|
153 |
- } |
|
154 |
- LzmaDec_Free() |
|
155 |
-*/ |
|
156 |
- |
|
157 |
-/* LzmaDec_DecodeToDic |
|
158 |
- |
|
159 |
- The decoding to internal dictionary buffer (CLzmaDec::dic). |
|
160 |
- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! |
|
161 |
- |
|
162 |
-finishMode: |
|
163 |
- It has meaning only if the decoding reaches output limit (dicLimit). |
|
164 |
- LZMA_FINISH_ANY - Decode just dicLimit bytes. |
|
165 |
- LZMA_FINISH_END - Stream must be finished after dicLimit. |
|
166 |
- |
|
167 |
-Returns: |
|
168 |
- SZ_OK |
|
169 |
- status: |
|
170 |
- LZMA_STATUS_FINISHED_WITH_MARK |
|
171 |
- LZMA_STATUS_NOT_FINISHED |
|
172 |
- LZMA_STATUS_NEEDS_MORE_INPUT |
|
173 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
174 |
- SZ_ERROR_DATA - Data error |
|
175 |
-*/ |
|
176 |
- |
|
177 |
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, |
|
178 |
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
179 |
- |
|
180 |
- |
|
181 |
-/* ---------- Buffer Interface ---------- */ |
|
182 |
- |
|
183 |
-/* It's zlib-like interface. |
|
184 |
- See LzmaDec_DecodeToDic description for information about STEPS and return results, |
|
185 |
- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need |
|
186 |
- to work with CLzmaDec variables manually. |
|
187 |
- |
|
188 |
-finishMode: |
|
189 |
- It has meaning only if the decoding reaches output limit (*destLen). |
|
190 |
- LZMA_FINISH_ANY - Decode just destLen bytes. |
|
191 |
- LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
192 |
-*/ |
|
193 |
- |
|
194 |
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, |
|
195 |
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
196 |
- |
|
197 |
- |
|
198 |
-/* ---------- One Call Interface ---------- */ |
|
199 |
- |
|
200 |
-/* LzmaDecode |
|
201 |
- |
|
202 |
-finishMode: |
|
203 |
- It has meaning only if the decoding reaches output limit (*destLen). |
|
204 |
- LZMA_FINISH_ANY - Decode just destLen bytes. |
|
205 |
- LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
206 |
- |
|
207 |
-Returns: |
|
208 |
- SZ_OK |
|
209 |
- status: |
|
210 |
- LZMA_STATUS_FINISHED_WITH_MARK |
|
211 |
- LZMA_STATUS_NOT_FINISHED |
|
212 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
213 |
- SZ_ERROR_DATA - Data error |
|
214 |
- SZ_ERROR_MEM - Memory allocation error |
|
215 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
216 |
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). |
|
217 |
-*/ |
|
218 |
- |
|
219 |
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
220 |
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
221 |
- ELzmaStatus *status, ISzAlloc *alloc); |
|
222 |
- |
|
223 |
-#endif |
|
1 |
+/* LzmaDec.h -- LZMA Decoder |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __LZMADEC_H |
|
5 |
+#define __LZMADEC_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+/* #define _LZMA_PROB32 */ |
|
10 |
+/* _LZMA_PROB32 can increase the speed on some CPUs, |
|
11 |
+ but memory usage for CLzmaDec::probs will be doubled in that case */ |
|
12 |
+ |
|
13 |
+#ifdef _LZMA_PROB32 |
|
14 |
+#define CLzmaProb UInt32 |
|
15 |
+#else |
|
16 |
+#define CLzmaProb UInt16 |
|
17 |
+#endif |
|
18 |
+ |
|
19 |
+ |
|
20 |
+/* ---------- LZMA Properties ---------- */ |
|
21 |
+ |
|
22 |
+#define LZMA_PROPS_SIZE 5 |
|
23 |
+ |
|
24 |
+typedef struct _CLzmaProps |
|
25 |
+{ |
|
26 |
+ unsigned lc, lp, pb; |
|
27 |
+ UInt32 dicSize; |
|
28 |
+} CLzmaProps; |
|
29 |
+ |
|
30 |
+/* LzmaProps_Decode - decodes properties |
|
31 |
+Returns: |
|
32 |
+ SZ_OK |
|
33 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
34 |
+*/ |
|
35 |
+ |
|
36 |
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); |
|
37 |
+ |
|
38 |
+ |
|
39 |
+/* ---------- LZMA Decoder state ---------- */ |
|
40 |
+ |
|
41 |
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. |
|
42 |
+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ |
|
43 |
+ |
|
44 |
+#define LZMA_REQUIRED_INPUT_MAX 20 |
|
45 |
+ |
|
46 |
+typedef struct |
|
47 |
+{ |
|
48 |
+ CLzmaProps prop; |
|
49 |
+ CLzmaProb *probs; |
|
50 |
+ Byte *dic; |
|
51 |
+ const Byte *buf; |
|
52 |
+ UInt32 range, code; |
|
53 |
+ SizeT dicPos; |
|
54 |
+ SizeT dicBufSize; |
|
55 |
+ UInt32 processedPos; |
|
56 |
+ UInt32 checkDicSize; |
|
57 |
+ unsigned state; |
|
58 |
+ UInt32 reps[4]; |
|
59 |
+ unsigned remainLen; |
|
60 |
+ int needFlush; |
|
61 |
+ int needInitState; |
|
62 |
+ UInt32 numProbs; |
|
63 |
+ unsigned tempBufSize; |
|
64 |
+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; |
|
65 |
+} CLzmaDec; |
|
66 |
+ |
|
67 |
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } |
|
68 |
+ |
|
69 |
+void LzmaDec_Init(CLzmaDec *p); |
|
70 |
+ |
|
71 |
+/* There are two types of LZMA streams: |
|
72 |
+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. |
|
73 |
+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ |
|
74 |
+ |
|
75 |
+typedef enum |
|
76 |
+{ |
|
77 |
+ LZMA_FINISH_ANY, /* finish at any point */ |
|
78 |
+ LZMA_FINISH_END /* block must be finished at the end */ |
|
79 |
+} ELzmaFinishMode; |
|
80 |
+ |
|
81 |
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! |
|
82 |
+ |
|
83 |
+ You must use LZMA_FINISH_END, when you know that current output buffer |
|
84 |
+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. |
|
85 |
+ |
|
86 |
+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, |
|
87 |
+ and output value of destLen will be less than output buffer size limit. |
|
88 |
+ You can check status result also. |
|
89 |
+ |
|
90 |
+ You can use multiple checks to test data integrity after full decompression: |
|
91 |
+ 1) Check Result and "status" variable. |
|
92 |
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. |
|
93 |
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. |
|
94 |
+ You must use correct finish mode in that case. */ |
|
95 |
+ |
|
96 |
+typedef enum |
|
97 |
+{ |
|
98 |
+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ |
|
99 |
+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ |
|
100 |
+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ |
|
101 |
+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ |
|
102 |
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ |
|
103 |
+} ELzmaStatus; |
|
104 |
+ |
|
105 |
+/* ELzmaStatus is used only as output value for function call */ |
|
106 |
+ |
|
107 |
+ |
|
108 |
+/* ---------- Interfaces ---------- */ |
|
109 |
+ |
|
110 |
+/* There are 3 levels of interfaces: |
|
111 |
+ 1) Dictionary Interface |
|
112 |
+ 2) Buffer Interface |
|
113 |
+ 3) One Call Interface |
|
114 |
+ You can select any of these interfaces, but don't mix functions from different |
|
115 |
+ groups for same object. */ |
|
116 |
+ |
|
117 |
+ |
|
118 |
+/* There are two variants to allocate state for Dictionary Interface: |
|
119 |
+ 1) LzmaDec_Allocate / LzmaDec_Free |
|
120 |
+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs |
|
121 |
+ You can use variant 2, if you set dictionary buffer manually. |
|
122 |
+ For Buffer Interface you must always use variant 1. |
|
123 |
+ |
|
124 |
+LzmaDec_Allocate* can return: |
|
125 |
+ SZ_OK |
|
126 |
+ SZ_ERROR_MEM - Memory allocation error |
|
127 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
128 |
+*/ |
|
129 |
+ |
|
130 |
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); |
|
131 |
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); |
|
132 |
+ |
|
133 |
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); |
|
134 |
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); |
|
135 |
+ |
|
136 |
+/* ---------- Dictionary Interface ---------- */ |
|
137 |
+ |
|
138 |
+/* You can use it, if you want to eliminate the overhead for data copying from |
|
139 |
+ dictionary to some other external buffer. |
|
140 |
+ You must work with CLzmaDec variables directly in this interface. |
|
141 |
+ |
|
142 |
+ STEPS: |
|
143 |
+ LzmaDec_Constr() |
|
144 |
+ LzmaDec_Allocate() |
|
145 |
+ for (each new stream) |
|
146 |
+ { |
|
147 |
+ LzmaDec_Init() |
|
148 |
+ while (it needs more decompression) |
|
149 |
+ { |
|
150 |
+ LzmaDec_DecodeToDic() |
|
151 |
+ use data from CLzmaDec::dic and update CLzmaDec::dicPos |
|
152 |
+ } |
|
153 |
+ } |
|
154 |
+ LzmaDec_Free() |
|
155 |
+*/ |
|
156 |
+ |
|
157 |
+/* LzmaDec_DecodeToDic |
|
158 |
+ |
|
159 |
+ The decoding to internal dictionary buffer (CLzmaDec::dic). |
|
160 |
+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! |
|
161 |
+ |
|
162 |
+finishMode: |
|
163 |
+ It has meaning only if the decoding reaches output limit (dicLimit). |
|
164 |
+ LZMA_FINISH_ANY - Decode just dicLimit bytes. |
|
165 |
+ LZMA_FINISH_END - Stream must be finished after dicLimit. |
|
166 |
+ |
|
167 |
+Returns: |
|
168 |
+ SZ_OK |
|
169 |
+ status: |
|
170 |
+ LZMA_STATUS_FINISHED_WITH_MARK |
|
171 |
+ LZMA_STATUS_NOT_FINISHED |
|
172 |
+ LZMA_STATUS_NEEDS_MORE_INPUT |
|
173 |
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
174 |
+ SZ_ERROR_DATA - Data error |
|
175 |
+*/ |
|
176 |
+ |
|
177 |
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, |
|
178 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
179 |
+ |
|
180 |
+ |
|
181 |
+/* ---------- Buffer Interface ---------- */ |
|
182 |
+ |
|
183 |
+/* It's zlib-like interface. |
|
184 |
+ See LzmaDec_DecodeToDic description for information about STEPS and return results, |
|
185 |
+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need |
|
186 |
+ to work with CLzmaDec variables manually. |
|
187 |
+ |
|
188 |
+finishMode: |
|
189 |
+ It has meaning only if the decoding reaches output limit (*destLen). |
|
190 |
+ LZMA_FINISH_ANY - Decode just destLen bytes. |
|
191 |
+ LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
192 |
+*/ |
|
193 |
+ |
|
194 |
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, |
|
195 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
196 |
+ |
|
197 |
+ |
|
198 |
+/* ---------- One Call Interface ---------- */ |
|
199 |
+ |
|
200 |
+/* LzmaDecode |
|
201 |
+ |
|
202 |
+finishMode: |
|
203 |
+ It has meaning only if the decoding reaches output limit (*destLen). |
|
204 |
+ LZMA_FINISH_ANY - Decode just destLen bytes. |
|
205 |
+ LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
206 |
+ |
|
207 |
+Returns: |
|
208 |
+ SZ_OK |
|
209 |
+ status: |
|
210 |
+ LZMA_STATUS_FINISHED_WITH_MARK |
|
211 |
+ LZMA_STATUS_NOT_FINISHED |
|
212 |
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
213 |
+ SZ_ERROR_DATA - Data error |
|
214 |
+ SZ_ERROR_MEM - Memory allocation error |
|
215 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
216 |
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). |
|
217 |
+*/ |
|
218 |
+ |
|
219 |
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
220 |
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
221 |
+ ELzmaStatus *status, ISzAlloc *alloc); |
|
222 |
+ |
|
223 |
+#endif |
... | ... |
@@ -1,213 +1,213 @@ |
1 |
-/* Types.h -- Basic types |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_TYPES_H |
|
5 |
-#define __7Z_TYPES_H |
|
6 |
- |
|
7 |
-#include <stddef.h> |
|
8 |
- |
|
9 |
-#ifdef _WIN32 |
|
10 |
-#include <windows.h> |
|
11 |
-#endif |
|
12 |
- |
|
13 |
-/* aCaB -- lame workaround for "Byte" refef */ |
|
14 |
-#include <zconf.h> |
|
15 |
- |
|
16 |
-#define SZ_OK 0 |
|
17 |
- |
|
18 |
-#define SZ_ERROR_DATA 1 |
|
19 |
-#define SZ_ERROR_MEM 2 |
|
20 |
-#define SZ_ERROR_CRC 3 |
|
21 |
-#define SZ_ERROR_UNSUPPORTED 4 |
|
22 |
-#define SZ_ERROR_PARAM 5 |
|
23 |
-#define SZ_ERROR_INPUT_EOF 6 |
|
24 |
-#define SZ_ERROR_OUTPUT_EOF 7 |
|
25 |
-#define SZ_ERROR_READ 8 |
|
26 |
-#define SZ_ERROR_WRITE 9 |
|
27 |
-#define SZ_ERROR_PROGRESS 10 |
|
28 |
-#define SZ_ERROR_FAIL 11 |
|
29 |
-#define SZ_ERROR_THREAD 12 |
|
30 |
- |
|
31 |
-#define SZ_ERROR_ARCHIVE 16 |
|
32 |
-#define SZ_ERROR_NO_ARCHIVE 17 |
|
33 |
- |
|
34 |
-typedef int SRes; |
|
35 |
- |
|
36 |
-#ifdef _WIN32 |
|
37 |
-typedef DWORD WRes; |
|
38 |
-#else |
|
39 |
-typedef int WRes; |
|
40 |
-#endif |
|
41 |
- |
|
42 |
-#ifndef RINOK |
|
43 |
-#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } |
|
44 |
-#endif |
|
45 |
- |
|
46 |
-/* aCaB -- use Byte defined in zconf.h |
|
47 |
-typedef unsigned char Byte; |
|
48 |
-*/ |
|
49 |
-typedef short Int16; |
|
50 |
-typedef unsigned short UInt16; |
|
51 |
- |
|
52 |
-#ifdef _LZMA_UINT32_IS_ULONG |
|
53 |
-typedef long Int32; |
|
54 |
-typedef unsigned long UInt32; |
|
55 |
-#else |
|
56 |
-typedef int Int32; |
|
57 |
-typedef unsigned int UInt32; |
|
58 |
-#endif |
|
59 |
- |
|
60 |
-#ifdef _SZ_NO_INT_64 |
|
61 |
- |
|
62 |
-/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. |
|
63 |
- NOTES: Some code will work incorrectly in that case! */ |
|
64 |
- |
|
65 |
-typedef long Int64; |
|
66 |
-typedef unsigned long UInt64; |
|
67 |
- |
|
68 |
-#else |
|
69 |
- |
|
70 |
-#if defined(_MSC_VER) || defined(__BORLANDC__) |
|
71 |
-typedef __int64 Int64; |
|
72 |
-typedef unsigned __int64 UInt64; |
|
73 |
-#else |
|
74 |
-typedef long long int Int64; |
|
75 |
-typedef unsigned long long int UInt64; |
|
76 |
-#endif |
|
77 |
- |
|
78 |
-#endif |
|
79 |
- |
|
80 |
-#ifdef _LZMA_NO_SYSTEM_SIZE_T |
|
81 |
-typedef UInt32 SizeT; |
|
82 |
-#else |
|
83 |
-typedef size_t SizeT; |
|
84 |
-#endif |
|
85 |
- |
|
86 |
-typedef int Bool; |
|
87 |
-#define True 1 |
|
88 |
-#define False 0 |
|
89 |
- |
|
90 |
- |
|
91 |
-#ifdef _MSC_VER |
|
92 |
- |
|
93 |
-#if _MSC_VER >= 1300 |
|
94 |
-#define MY_NO_INLINE __declspec(noinline) |
|
95 |
-#else |
|
96 |
-#define MY_NO_INLINE |
|
97 |
-#endif |
|
98 |
- |
|
99 |
-#define MY_CDECL __cdecl |
|
100 |
-#define MY_STD_CALL __stdcall |
|
101 |
-#define MY_FAST_CALL MY_NO_INLINE __fastcall |
|
102 |
- |
|
103 |
-#else |
|
104 |
- |
|
105 |
-#define MY_CDECL |
|
106 |
-#define MY_STD_CALL |
|
107 |
-#define MY_FAST_CALL |
|
108 |
- |
|
109 |
-#endif |
|
110 |
- |
|
111 |
- |
|
112 |
-/* The following interfaces use first parameter as pointer to structure */ |
|
113 |
- |
|
114 |
-typedef struct |
|
115 |
-{ |
|
116 |
- SRes (*Read)(void *p, void *buf, size_t *size); |
|
117 |
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
118 |
- (output(*size) < input(*size)) is allowed */ |
|
119 |
-} ISeqInStream; |
|
120 |
- |
|
121 |
-/* it can return SZ_ERROR_INPUT_EOF */ |
|
122 |
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); |
|
123 |
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); |
|
124 |
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); |
|
125 |
- |
|
126 |
-typedef struct |
|
127 |
-{ |
|
128 |
- size_t (*Write)(void *p, const void *buf, size_t size); |
|
129 |
- /* Returns: result - the number of actually written bytes. |
|
130 |
- (result < size) means error */ |
|
131 |
-} ISeqOutStream; |
|
132 |
- |
|
133 |
-typedef enum |
|
134 |
-{ |
|
135 |
- SZ_SEEK_SET = 0, |
|
136 |
- SZ_SEEK_CUR = 1, |
|
137 |
- SZ_SEEK_END = 2 |
|
138 |
-} ESzSeek; |
|
139 |
- |
|
140 |
-typedef struct |
|
141 |
-{ |
|
142 |
- SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ |
|
143 |
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
144 |
-} ISeekInStream; |
|
145 |
- |
|
146 |
-typedef struct |
|
147 |
-{ |
|
148 |
- SRes (*Look)(void *p, void **buf, size_t *size); |
|
149 |
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
150 |
- (output(*size) > input(*size)) is not allowed |
|
151 |
- (output(*size) < input(*size)) is allowed */ |
|
152 |
- SRes (*Skip)(void *p, size_t offset); |
|
153 |
- /* offset must be <= output(*size) of Look */ |
|
154 |
- |
|
155 |
- SRes (*Read)(void *p, void *buf, size_t *size); |
|
156 |
- /* reads directly (without buffer). It's same as ISeqInStream::Read */ |
|
157 |
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
158 |
-} ILookInStream; |
|
159 |
- |
|
160 |
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); |
|
161 |
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); |
|
162 |
- |
|
163 |
-/* reads via ILookInStream::Read */ |
|
164 |
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); |
|
165 |
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); |
|
166 |
- |
|
167 |
-#define LookToRead_BUF_SIZE (1 << 14) |
|
168 |
- |
|
169 |
-typedef struct |
|
170 |
-{ |
|
171 |
- ILookInStream s; |
|
172 |
- ISeekInStream *realStream; |
|
173 |
- size_t pos; |
|
174 |
- size_t size; |
|
175 |
- Byte buf[LookToRead_BUF_SIZE]; |
|
176 |
-} CLookToRead; |
|
177 |
- |
|
178 |
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead); |
|
179 |
-void LookToRead_Init(CLookToRead *p); |
|
180 |
- |
|
181 |
-typedef struct |
|
182 |
-{ |
|
183 |
- ISeqInStream s; |
|
184 |
- ILookInStream *realStream; |
|
185 |
-} CSecToLook; |
|
186 |
- |
|
187 |
-void SecToLook_CreateVTable(CSecToLook *p); |
|
188 |
- |
|
189 |
-typedef struct |
|
190 |
-{ |
|
191 |
- ISeqInStream s; |
|
192 |
- ILookInStream *realStream; |
|
193 |
-} CSecToRead; |
|
194 |
- |
|
195 |
-void SecToRead_CreateVTable(CSecToRead *p); |
|
196 |
- |
|
197 |
-typedef struct |
|
198 |
-{ |
|
199 |
- SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); |
|
200 |
- /* Returns: result. (result != SZ_OK) means break. |
|
201 |
- Value (UInt64)(Int64)-1 for size means unknown value. */ |
|
202 |
-} ICompressProgress; |
|
203 |
- |
|
204 |
-typedef struct |
|
205 |
-{ |
|
206 |
- void *(*Alloc)(void *p, size_t size); |
|
207 |
- void (*Free)(void *p, void *address); /* address can be 0 */ |
|
208 |
-} ISzAlloc; |
|
209 |
- |
|
210 |
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) |
|
211 |
-#define IAlloc_Free(p, a) (p)->Free((p), a) |
|
212 |
- |
|
213 |
-#endif |
|
1 |
+/* Types.h -- Basic types |
|
2 |
+2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_TYPES_H |
|
5 |
+#define __7Z_TYPES_H |
|
6 |
+ |
|
7 |
+#include <stddef.h> |
|
8 |
+ |
|
9 |
+#ifdef _WIN32 |
|
10 |
+#include <windows.h> |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+/* aCaB -- lame workaround for "Byte" refef */ |
|
14 |
+#include <zconf.h> |
|
15 |
+ |
|
16 |
+#define SZ_OK 0 |
|
17 |
+ |
|
18 |
+#define SZ_ERROR_DATA 1 |
|
19 |
+#define SZ_ERROR_MEM 2 |
|
20 |
+#define SZ_ERROR_CRC 3 |
|
21 |
+#define SZ_ERROR_UNSUPPORTED 4 |
|
22 |
+#define SZ_ERROR_PARAM 5 |
|
23 |
+#define SZ_ERROR_INPUT_EOF 6 |
|
24 |
+#define SZ_ERROR_OUTPUT_EOF 7 |
|
25 |
+#define SZ_ERROR_READ 8 |
|
26 |
+#define SZ_ERROR_WRITE 9 |
|
27 |
+#define SZ_ERROR_PROGRESS 10 |
|
28 |
+#define SZ_ERROR_FAIL 11 |
|
29 |
+#define SZ_ERROR_THREAD 12 |
|
30 |
+ |
|
31 |
+#define SZ_ERROR_ARCHIVE 16 |
|
32 |
+#define SZ_ERROR_NO_ARCHIVE 17 |
|
33 |
+ |
|
34 |
+typedef int SRes; |
|
35 |
+ |
|
36 |
+#ifdef _WIN32 |
|
37 |
+typedef DWORD WRes; |
|
38 |
+#else |
|
39 |
+typedef int WRes; |
|
40 |
+#endif |
|
41 |
+ |
|
42 |
+#ifndef RINOK |
|
43 |
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } |
|
44 |
+#endif |
|
45 |
+ |
|
46 |
+/* aCaB -- use Byte defined in zconf.h |
|
47 |
+typedef unsigned char Byte; |
|
48 |
+*/ |
|
49 |
+typedef short Int16; |
|
50 |
+typedef unsigned short UInt16; |
|
51 |
+ |
|
52 |
+#ifdef _LZMA_UINT32_IS_ULONG |
|
53 |
+typedef long Int32; |
|
54 |
+typedef unsigned long UInt32; |
|
55 |
+#else |
|
56 |
+typedef int Int32; |
|
57 |
+typedef unsigned int UInt32; |
|
58 |
+#endif |
|
59 |
+ |
|
60 |
+#ifdef _SZ_NO_INT_64 |
|
61 |
+ |
|
62 |
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. |
|
63 |
+ NOTES: Some code will work incorrectly in that case! */ |
|
64 |
+ |
|
65 |
+typedef long Int64; |
|
66 |
+typedef unsigned long UInt64; |
|
67 |
+ |
|
68 |
+#else |
|
69 |
+ |
|
70 |
+#if defined(_MSC_VER) || defined(__BORLANDC__) |
|
71 |
+typedef __int64 Int64; |
|
72 |
+typedef unsigned __int64 UInt64; |
|
73 |
+#else |
|
74 |
+typedef long long int Int64; |
|
75 |
+typedef unsigned long long int UInt64; |
|
76 |
+#endif |
|
77 |
+ |
|
78 |
+#endif |
|
79 |
+ |
|
80 |
+#ifdef _LZMA_NO_SYSTEM_SIZE_T |
|
81 |
+typedef UInt32 SizeT; |
|
82 |
+#else |
|
83 |
+typedef size_t SizeT; |
|
84 |
+#endif |
|
85 |
+ |
|
86 |
+typedef int Bool; |
|
87 |
+#define True 1 |
|
88 |
+#define False 0 |
|
89 |
+ |
|
90 |
+ |
|
91 |
+#ifdef _MSC_VER |
|
92 |
+ |
|
93 |
+#if _MSC_VER >= 1300 |
|
94 |
+#define MY_NO_INLINE __declspec(noinline) |
|
95 |
+#else |
|
96 |
+#define MY_NO_INLINE |
|
97 |
+#endif |
|
98 |
+ |
|
99 |
+#define MY_CDECL __cdecl |
|
100 |
+#define MY_STD_CALL __stdcall |
|
101 |
+#define MY_FAST_CALL MY_NO_INLINE __fastcall |
|
102 |
+ |
|
103 |
+#else |
|
104 |
+ |
|
105 |
+#define MY_CDECL |
|
106 |
+#define MY_STD_CALL |
|
107 |
+#define MY_FAST_CALL |
|
108 |
+ |
|
109 |
+#endif |
|
110 |
+ |
|
111 |
+ |
|
112 |
+/* The following interfaces use first parameter as pointer to structure */ |
|
113 |
+ |
|
114 |
+typedef struct |
|
115 |
+{ |
|
116 |
+ SRes (*Read)(void *p, void *buf, size_t *size); |
|
117 |
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
118 |
+ (output(*size) < input(*size)) is allowed */ |
|
119 |
+} ISeqInStream; |
|
120 |
+ |
|
121 |
+/* it can return SZ_ERROR_INPUT_EOF */ |
|
122 |
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); |
|
123 |
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); |
|
124 |
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); |
|
125 |
+ |
|
126 |
+typedef struct |
|
127 |
+{ |
|
128 |
+ size_t (*Write)(void *p, const void *buf, size_t size); |
|
129 |
+ /* Returns: result - the number of actually written bytes. |
|
130 |
+ (result < size) means error */ |
|
131 |
+} ISeqOutStream; |
|
132 |
+ |
|
133 |
+typedef enum |
|
134 |
+{ |
|
135 |
+ SZ_SEEK_SET = 0, |
|
136 |
+ SZ_SEEK_CUR = 1, |
|
137 |
+ SZ_SEEK_END = 2 |
|
138 |
+} ESzSeek; |
|
139 |
+ |
|
140 |
+typedef struct |
|
141 |
+{ |
|
142 |
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ |
|
143 |
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
144 |
+} ISeekInStream; |
|
145 |
+ |
|
146 |
+typedef struct |
|
147 |
+{ |
|
148 |
+ SRes (*Look)(void *p, void **buf, size_t *size); |
|
149 |
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
150 |
+ (output(*size) > input(*size)) is not allowed |
|
151 |
+ (output(*size) < input(*size)) is allowed */ |
|
152 |
+ SRes (*Skip)(void *p, size_t offset); |
|
153 |
+ /* offset must be <= output(*size) of Look */ |
|
154 |
+ |
|
155 |
+ SRes (*Read)(void *p, void *buf, size_t *size); |
|
156 |
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ |
|
157 |
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
158 |
+} ILookInStream; |
|
159 |
+ |
|
160 |
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); |
|
161 |
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); |
|
162 |
+ |
|
163 |
+/* reads via ILookInStream::Read */ |
|
164 |
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); |
|
165 |
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); |
|
166 |
+ |
|
167 |
+#define LookToRead_BUF_SIZE (1 << 14) |
|
168 |
+ |
|
169 |
+typedef struct |
|
170 |
+{ |
|
171 |
+ ILookInStream s; |
|
172 |
+ ISeekInStream *realStream; |
|
173 |
+ size_t pos; |
|
174 |
+ size_t size; |
|
175 |
+ Byte buf[LookToRead_BUF_SIZE]; |
|
176 |
+} CLookToRead; |
|
177 |
+ |
|
178 |
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); |
|
179 |
+void LookToRead_Init(CLookToRead *p); |
|
180 |
+ |
|
181 |
+typedef struct |
|
182 |
+{ |
|
183 |
+ ISeqInStream s; |
|
184 |
+ ILookInStream *realStream; |
|
185 |
+} CSecToLook; |
|
186 |
+ |
|
187 |
+void SecToLook_CreateVTable(CSecToLook *p); |
|
188 |
+ |
|
189 |
+typedef struct |
|
190 |
+{ |
|
191 |
+ ISeqInStream s; |
|
192 |
+ ILookInStream *realStream; |
|
193 |
+} CSecToRead; |
|
194 |
+ |
|
195 |
+void SecToRead_CreateVTable(CSecToRead *p); |
|
196 |
+ |
|
197 |
+typedef struct |
|
198 |
+{ |
|
199 |
+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); |
|
200 |
+ /* Returns: result. (result != SZ_OK) means break. |
|
201 |
+ Value (UInt64)(Int64)-1 for size means unknown value. */ |
|
202 |
+} ICompressProgress; |
|
203 |
+ |
|
204 |
+typedef struct |
|
205 |
+{ |
|
206 |
+ void *(*Alloc)(void *p, size_t size); |
|
207 |
+ void (*Free)(void *p, void *address); /* address can be 0 */ |
|
208 |
+} ISzAlloc; |
|
209 |
+ |
|
210 |
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) |
|
211 |
+#define IAlloc_Free(p, a) (p)->Free((p), a) |
|
212 |
+ |
|
213 |
+#endif |