File size: 4,883 Bytes
92c4149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
 * Ref https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
 */
import { UINT16_LE, UINT32_LE } from "token-types";
export const Signature = {
    LocalFileHeader: 0x04034b50,
    DataDescriptor: 0x08074b50,
    CentralFileHeader: 0x02014b50,
    EndOfCentralDirectory: 0x06054b50
};
export const DataDescriptor = {
    get(array) {
        const flags = UINT16_LE.get(array, 6);
        return {
            signature: UINT32_LE.get(array, 0),
            compressedSize: UINT32_LE.get(array, 8),
            uncompressedSize: UINT32_LE.get(array, 12),
        };
    }, len: 16
};
/**
 * First part of the ZIP Local File Header
 * Offset | Bytes| Description
 * -------|------+-------------------------------------------------------------------
 *      0 |    4 | Signature (0x04034b50)
 *      4 |    2 | Minimum version needed to extract
 *      6 |    2 | Bit flag
 *      8 |    2 | Compression method
 *     10 |    2 | File last modification time (MS-DOS format)
 *     12 |    2 | File last modification date (MS-DOS format)
 *     14 |    4 | CRC-32 of uncompressed data
 *     18 |    4 | Compressed size
 *     22 |    4 | Uncompressed size
 *     26 |    2 | File name length (n)
 *     28 |    2 | Extra field length (m)
 *     30 |    n | File name
 * 30 + n |    m | Extra field
 */
export const LocalFileHeaderToken = {
    get(array) {
        const flags = UINT16_LE.get(array, 6);
        return {
            signature: UINT32_LE.get(array, 0),
            minVersion: UINT16_LE.get(array, 4),
            dataDescriptor: !!(flags & 0x0008),
            compressedMethod: UINT16_LE.get(array, 8),
            compressedSize: UINT32_LE.get(array, 18),
            uncompressedSize: UINT32_LE.get(array, 22),
            filenameLength: UINT16_LE.get(array, 26),
            extraFieldLength: UINT16_LE.get(array, 28),
            filename: null
        };
    }, len: 30
};
/**
 * 4.3.16  End of central directory record:
 *  end of central dir signature (0x06064b50)                                      4 bytes
 *  number of this disk                                                            2 bytes
 *  number of the disk with the start of the central directory                     2 bytes
 *  total number of entries in the central directory on this disk                  2 bytes
 *  total number of entries in the size of the central directory                   2 bytes
 *  sizeOfTheCentralDirectory                                                      4 bytes
 *  offset of start of central directory with respect to the starting disk number  4 bytes
 *  .ZIP file comment length                                                       2 bytes
 *  .ZIP file comment       (variable size)
 */
export const EndOfCentralDirectoryRecordToken = {
    get(array) {
        return {
            signature: UINT32_LE.get(array, 0),
            nrOfThisDisk: UINT16_LE.get(array, 4),
            nrOfThisDiskWithTheStart: UINT16_LE.get(array, 6),
            nrOfEntriesOnThisDisk: UINT16_LE.get(array, 8),
            nrOfEntriesOfSize: UINT16_LE.get(array, 10),
            sizeOfCd: UINT32_LE.get(array, 12),
            offsetOfStartOfCd: UINT32_LE.get(array, 16),
            zipFileCommentLength: UINT16_LE.get(array, 20),
        };
    }, len: 22
};
/**
 * File header:
 *    central file header signature   4 bytes   0 (0x02014b50)
 *    version made by                 2 bytes   4
 *    version needed to extract       2 bytes   6
 *    general purpose bit flag        2 bytes   8
 *    compression method              2 bytes  10
 *    last mod file time              2 bytes  12
 *    last mod file date              2 bytes  14
 *    crc-32                          4 bytes  16
 *    compressed size                 4 bytes  20
 *    uncompressed size               4 bytes  24
 *    file name length                2 bytes  28
 *    extra field length              2 bytes  30
 *    file comment length             2 bytes  32
 *    disk number start               2 bytes  34
 *    internal file attributes        2 bytes  36
 *    external file attributes        4 bytes  38
 *    relative offset of local header 4 bytes  42
 */
export const FileHeader = {
    get(array) {
        const flags = UINT16_LE.get(array, 8);
        return {
            signature: UINT32_LE.get(array, 0),
            minVersion: UINT16_LE.get(array, 6),
            dataDescriptor: !!(flags & 0x0008),
            compressedMethod: UINT16_LE.get(array, 10),
            compressedSize: UINT32_LE.get(array, 20),
            uncompressedSize: UINT32_LE.get(array, 24),
            filenameLength: UINT16_LE.get(array, 28),
            extraFieldLength: UINT16_LE.get(array, 30),
            fileCommentLength: UINT16_LE.get(array, 32),
            relativeOffsetOfLocalHeader: UINT32_LE.get(array, 42),
            filename: null
        };
    }, len: 46
};