| 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 TOOD(adriansc): Remove this file once the dependency has been updated in WebKit | 9 TOOD(adriansc): Remove this file once the dependency has been updated in WebKit |
| 10 to point to grit scripts. | 10 to point to grit scripts. |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 import struct | 13 import struct |
| 14 | 14 |
| 15 FILE_FORMAT_VERSION = 4 | 15 FILE_FORMAT_VERSION = 3 |
| 16 HEADER_LENGTH = 2 * 4 + 1 # Two uint32s. (file version, number of entries) and | 16 HEADER_LENGTH = 2 * 4 # Two uint32s. (file version and number of entries) |
| 17 # one uint8 (encoding of text resources) | |
| 18 BINARY, UTF8, UTF16 = range(3) | |
| 19 | 17 |
| 20 class WrongFileVersion(Exception): | 18 class WrongFileVersion(Exception): |
| 21 pass | 19 pass |
| 22 | 20 |
| 23 class DataPackContents: | |
| 24 def __init__(self, resources, encoding): | |
| 25 self.resources = resources | |
| 26 self.encoding = encoding | |
| 27 | |
| 28 def ReadDataPack(input_file): | 21 def ReadDataPack(input_file): |
| 29 """Reads a data pack file and returns a dictionary.""" | 22 """Reads a data pack file and returns a dictionary.""" |
| 30 data = open(input_file, "rb").read() | 23 data = open(input_file, "rb").read() |
| 31 original_data = data | 24 original_data = data |
| 32 | 25 |
| 33 # Read the header. | 26 # Read the header. |
| 34 version, num_entries, encoding = struct.unpack("<IIB", data[:HEADER_LENGTH]) | 27 version, num_entries = struct.unpack("<II", data[:HEADER_LENGTH]) |
| 35 if version != FILE_FORMAT_VERSION: | 28 if version != FILE_FORMAT_VERSION: |
| 36 print "Wrong file version in ", input_file | |
| 37 raise WrongFileVersion | 29 raise WrongFileVersion |
| 38 | 30 |
| 39 resources = {} | 31 resources = {} |
| 40 if num_entries == 0: | 32 if num_entries == 0: |
| 41 return DataPackContents(resources, encoding) | 33 return resources |
| 42 | 34 |
| 43 # Read the index and data. | 35 # Read the index and data. |
| 44 data = data[HEADER_LENGTH:] | 36 data = data[HEADER_LENGTH:] |
| 45 kIndexEntrySize = 2 + 4 # Each entry is a uint16 and a uint32. | 37 kIndexEntrySize = 2 + 4 # Each entry is a uint16 and a uint32. |
| 46 for _ in range(num_entries): | 38 for _ in range(num_entries): |
| 47 id, offset = struct.unpack("<HI", data[:kIndexEntrySize]) | 39 id, offset = struct.unpack("<HI", data[:kIndexEntrySize]) |
| 48 data = data[kIndexEntrySize:] | 40 data = data[kIndexEntrySize:] |
| 49 next_id, next_offset = struct.unpack("<HI", data[:kIndexEntrySize]) | 41 next_id, next_offset = struct.unpack("<HI", data[:kIndexEntrySize]) |
| 50 resources[id] = original_data[offset:next_offset] | 42 resources[id] = original_data[offset:next_offset] |
| 51 | 43 |
| 52 return DataPackContents(resources, encoding) | 44 return resources |
| 53 | 45 |
| 54 def WriteDataPack(resources, output_file, encoding): | 46 def WriteDataPack(resources, output_file): |
| 55 """Write a map of id=>data into output_file as a data pack.""" | 47 """Write a map of id=>data into output_file as a data pack.""" |
| 56 ids = sorted(resources.keys()) | 48 ids = sorted(resources.keys()) |
| 57 file = open(output_file, "wb") | 49 file = open(output_file, "wb") |
| 58 | 50 |
| 59 # Write file header. | 51 # Write file header. |
| 60 file.write(struct.pack("<IIB", FILE_FORMAT_VERSION, len(ids), encoding)) | 52 file.write(struct.pack("<II", FILE_FORMAT_VERSION, len(ids))) |
| 61 | 53 |
| 62 # Each entry is a uint16 and a uint32. We have one extra entry for the last | 54 # Each entry is a uint16 and a uint32. We have one extra entry for the last |
| 63 # item. | 55 # item. |
| 64 index_length = (len(ids) + 1) * (2 + 4) | 56 index_length = (len(ids) + 1) * (2 + 4) |
| 65 | 57 |
| 66 # Write index. | 58 # Write index. |
| 67 data_offset = HEADER_LENGTH + index_length | 59 data_offset = HEADER_LENGTH + index_length |
| 68 for id in ids: | 60 for id in ids: |
| 69 file.write(struct.pack("<HI", id, data_offset)) | 61 file.write(struct.pack("<HI", id, data_offset)) |
| 70 data_offset += len(resources[id]) | 62 data_offset += len(resources[id]) |
| 71 | 63 |
| 72 file.write(struct.pack("<HI", 0, data_offset)) | 64 file.write(struct.pack("<HI", 0, data_offset)) |
| 73 | 65 |
| 74 # Write data. | 66 # Write data. |
| 75 for id in ids: | 67 for id in ids: |
| 76 file.write(resources[id]) | 68 file.write(resources[id]) |
| 77 | 69 |
| 78 def main(): | 70 def main(): |
| 79 # Just write a simple file. | 71 # Just write a simple file. |
| 80 data = { 1: "", 4: "this is id 4", 6: "this is id 6", 10: "" } | 72 data = { 1: "", 4: "this is id 4", 6: "this is id 6", 10: "" } |
| 81 WriteDataPack(data, "datapack1.pak", UTF8) | 73 WriteDataPack(data, "datapack1.pak") |
| 82 data2 = { 1000: "test", 5: "five" } | 74 data2 = { 1000: "test", 5: "five" } |
| 83 WriteDataPack(data2, "datapack2.pak", UTF8) | 75 WriteDataPack(data2, "datapack2.pak") |
| 84 print "wrote datapack1 and datapack2 to current directory." | 76 print "wrote datapack1 and datapack2 to current directory." |
| 85 | 77 |
| 86 if __name__ == '__main__': | 78 if __name__ == '__main__': |
| 87 main() | 79 main() |
| OLD | NEW |