OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """A simple utility function to produce data pack files. | 6 """A simple utility function to produce data pack files. |
7 See base/pack_file* for details. | 7 See base/pack_file* for details. |
8 """ | 8 """ |
9 | 9 |
10 import struct | 10 import struct |
11 | 11 |
12 FILE_FORMAT_VERSION = 2 | 12 FILE_FORMAT_VERSION = 3 |
13 HEADER_LENGTH = 2 * 4 # Two uint32s. (file version and number of entries) | 13 HEADER_LENGTH = 2 * 4 # Two uint32s. (file version and number of entries) |
14 | 14 |
15 class WrongFileVersion(Exception): | 15 class WrongFileVersion(Exception): |
16 pass | 16 pass |
17 | 17 |
18 def ReadDataPack(input_file): | 18 def ReadDataPack(input_file): |
19 """Reads a data pack file and returns a dictionary.""" | 19 """Reads a data pack file and returns a dictionary.""" |
20 data = open(input_file, "rb").read() | 20 data = open(input_file, "rb").read() |
21 original_data = data | 21 original_data = data |
22 | 22 |
23 # Read the header. | 23 # Read the header. |
24 version, num_entries = struct.unpack("<II", data[:HEADER_LENGTH]) | 24 version, num_entries = struct.unpack("<II", data[:HEADER_LENGTH]) |
25 if version != FILE_FORMAT_VERSION: | 25 if version != FILE_FORMAT_VERSION: |
26 raise WrongFileVersion | 26 raise WrongFileVersion |
27 | 27 |
28 resources = {} | 28 resources = {} |
| 29 if num_entries == 0: |
| 30 return resources |
| 31 |
29 # Read the index and data. | 32 # Read the index and data. |
30 data = data[HEADER_LENGTH:] | 33 data = data[HEADER_LENGTH:] |
31 kIndexEntrySize = 2 + 2 * 4 # Each entry is 1 uint16 and 2 uint32s. | 34 kIndexEntrySize = 2 + 4 # Each entry is a uint16 and a uint32. |
32 for _ in range(num_entries): | 35 for _ in range(num_entries): |
33 id, offset, length = struct.unpack("<HII", data[:kIndexEntrySize]) | 36 id, offset = struct.unpack("<HI", data[:kIndexEntrySize]) |
34 data = data[kIndexEntrySize:] | 37 data = data[kIndexEntrySize:] |
35 resources[id] = original_data[offset:offset + length] | 38 next_id, next_offset = struct.unpack("<HI", data[:kIndexEntrySize]) |
| 39 resources[id] = original_data[offset:next_offset] |
36 | 40 |
37 return resources | 41 return resources |
38 | 42 |
39 def WriteDataPack(resources, output_file): | 43 def WriteDataPack(resources, output_file): |
40 """Write a map of id=>data into output_file as a data pack.""" | 44 """Write a map of id=>data into output_file as a data pack.""" |
41 ids = sorted(resources.keys()) | 45 ids = sorted(resources.keys()) |
42 file = open(output_file, "wb") | 46 file = open(output_file, "wb") |
43 | 47 |
44 # Write file header. | 48 # Write file header. |
45 file.write(struct.pack("<II", FILE_FORMAT_VERSION, len(ids))) | 49 file.write(struct.pack("<II", FILE_FORMAT_VERSION, len(ids))) |
46 | 50 |
47 # Each entry is 1 uint16 and 2 uint32s. | 51 # Each entry is a uint16 and a uint32. We have one extra entry for the last |
48 index_length = len(ids) * (2 + 2 * 4) | 52 # item. |
| 53 index_length = (len(ids) + 1) * (2 + 4) |
49 | 54 |
50 # Write index. | 55 # Write index. |
51 data_offset = HEADER_LENGTH + index_length | 56 data_offset = HEADER_LENGTH + index_length |
52 for id in ids: | 57 for id in ids: |
53 file.write(struct.pack("<HII", id, data_offset, len(resources[id]))) | 58 file.write(struct.pack("<HI", id, data_offset)) |
54 data_offset += len(resources[id]) | 59 data_offset += len(resources[id]) |
55 | 60 |
| 61 file.write(struct.pack("<HI", 0, data_offset)) |
| 62 |
56 # Write data. | 63 # Write data. |
57 for id in ids: | 64 for id in ids: |
58 file.write(resources[id]) | 65 file.write(resources[id]) |
59 | 66 |
60 def main(): | 67 def main(): |
61 # Just write a simple file. | 68 # Just write a simple file. |
62 data = { 1: "", 4: "this is id 4", 6: "this is id 6", 10: "" } | 69 data = { 1: "", 4: "this is id 4", 6: "this is id 6", 10: "" } |
63 WriteDataPack(data, "datapack1.pak") | 70 WriteDataPack(data, "datapack1.pak") |
64 data2 = { 1000: "test", 5: "five" } | 71 data2 = { 1000: "test", 5: "five" } |
65 WriteDataPack(data2, "datapack2.pak") | 72 WriteDataPack(data2, "datapack2.pak") |
66 print "wrote datapack1 and datapack2 to current directory." | 73 print "wrote datapack1 and datapack2 to current directory." |
67 | 74 |
68 if __name__ == '__main__': | 75 if __name__ == '__main__': |
69 main() | 76 main() |
OLD | NEW |