1 /*******************************************************************************
2 
3     Record definitions for the PKZIP archive file format
4 
5     copyright:  Copyright (c) 2016 dunnhumby Germany GmbH. All rights reserved
6 
7 
8 *******************************************************************************/
9 
10 module ocean.util.compress.c.Zip;
11 
12 
13 import ocean.meta.types.Qualifiers : istring;
14 
15 
16 /*******************************************************************************
17 
18     Signatures of the records in a Zip archive. Each record is preceded by the
19     corresponding signature, except for ZipLocalFileSizeSignature, which is
20     permitted to be missing.
21 
22     All signatures begin with "PK", the initials of Phil Katz, who created the
23     format.
24 
25 *******************************************************************************/
26 
27 static istring ZipCentralDirectoryFileHeaderSignature = "PK\x01\x02";
28 
29 /** ditto **/
30 
31 static istring ZipLocalFileHeaderSignature = "PK\x03\x04";
32 
33 /** ditto **/
34 
35 static istring ZipEndOfCentralDirectorySignature = "PK\x05\x06";
36 
37 /** ditto **/
38 
39 static istring ZipLocalFileSizeSignature = "PK\x07\x08";
40 
41 
42 
43 /*******************************************************************************
44 
45     Struct which is stored at the start of each file in the archive
46 
47     This record will always be preceded by a ZipLocalFileHeaderSignature.
48     This is an incomplete, redundant copy of the struct in the central
49     directory.
50 
51 *******************************************************************************/
52 
53 public align(1) struct ZipLocalFileHeaderRecord
54 {
55     align(1):
56     ushort      extract_version;
57     ushort      general_flags;
58     ushort      compression_method;
59     ushort      modification_file_time;
60     ushort      modification_file_date;
61     uint        crc_32;
62     uint        compressed_size;
63     uint        uncompressed_size;
64     ushort      file_name_length;
65     ushort      extra_field_length;
66 
67     /***********************************************************************
68 
69         Returns:
70             true if the CRC and file sizes were not known when the object
71             was written. In this case, the values are stored in a
72             ZipLocalFileSizeRecord after the compressed data. There may or
73             may not be a ZipLocalFileSizeSignature before the record.
74 
75     ***********************************************************************/
76 
77     public final bool isCrcMissing ( )
78     {
79         return (this.general_flags & 0x08 ) == 0x08;
80     }
81 
82 
83     /***************************************************************************
84 
85         Returns:
86             true if and only if the file is compressed using the DEFLATE method
87 
88     ***************************************************************************/
89 
90     public final bool isDeflateCompressed ()
91     {
92         return this.compression_method == 8;
93     }
94 }
95 
96 
97 /*******************************************************************************
98 
99     Struct which is stored at the end of a file if the CRC and length were not
100     known when the file compression began.
101 
102     This struct may optionally be preceded by a ZipLocalFileSizeSignature.
103 
104 *******************************************************************************/
105 
106 public align(1) struct ZipLocalFileSizeRecord
107 {
108     align(1):
109     uint        crc_32;
110     uint        compressed_size;
111     uint        uncompressed_size;
112 }
113 
114 
115 /*******************************************************************************
116 
117     Struct which is stored at the end of the archive. It is followed by a
118     comment of length up to 65535 bytes.
119 
120     This record will always be preceded by a
121     ZipCentralDirectoryFileHeaderSignature.
122 
123 *******************************************************************************/
124 
125 public align(1) struct ZipCentralDirectoryFileHeaderRecord
126 {
127     align(1):
128     ubyte       zip_version;
129     ubyte       file_attribute_type;
130     ushort      extract_version;
131     ushort      general_flags;
132     ushort      compression_method;
133     ushort      modification_file_time;
134     ushort      modification_file_date;
135     uint        crc_32;
136     uint        compressed_size;
137     uint        uncompressed_size;
138     ushort      file_name_length;
139     ushort      extra_field_length;
140     ushort      file_comment_length;
141     ushort      disk_number_start;
142     ushort      internal_file_attributes;
143     uint        external_file_attributes;
144     int         relative_offset_of_local_header;
145 }
146 
147 
148 /*******************************************************************************
149 
150     Struct which is stored at the end of the archive. It is followed by a
151     comment of length up to 65535 bytes.
152 
153     This record will always be preceded by a
154     ZipEndOfCentralDirectorySignature
155 
156 *******************************************************************************/
157 
158 public align(1) struct EndOfCentralDirectoryRecord
159 {
160     align(1):
161     ushort      disk_number;
162     ushort      disk_with_start_of_central_directory;
163     ushort      central_directory_entries_on_this_disk;
164     ushort      central_directory_entries_total;
165     uint        size_of_central_directory;
166     uint        offset_of_start_of_cd_from_starting_disk;
167     ushort      file_comment_length;
168 }