1# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2# 3# This Source Code Form is subject to the terms of the Mozilla Public 4# License, v. 2.0. If a copy of the MPL was not distributed with this 5# file, You can obtain one at http://mozilla.org/MPL/2.0/. 6# 7 8import sys 9import struct 10 11column_block_type = { 12 0 : "empty block", 13 1 : "numeric block", 14 2 : "string block" 15 } 16 17 18def parse_block(data, index): 19 start_row = struct.unpack('Q', data[index:index+8])[0] 20 index += 8 21 data_size = struct.unpack('Q', data[index:index+8])[0] 22 index += 8 23 block_type = struct.unpack('B', data[index:index+1])[0] 24 index += 1 25 vals = {} 26 if block_type == 1: 27 # numeric block 28 for i in range(data_size): 29 vals[start_row + i] = struct.unpack('d', data[index:index+8])[0] 30 index += 8 31 elif block_type == 2: 32 # string block 33 for i in range(data_size): 34 str_length = struct.unpack('i', data[index:index+4])[0] 35 index += 4 36 vals[start_row + i] = data[index:index+str_length].decode("utf-8") 37 index += str_length 38 elif block_type == 3: 39 # formula block 40 read_rows = 0 41 while read_rows < data_size: 42 formula_group_size = struct.unpack('Q', data[index:index+8])[0] 43 index += 8 44 str_length = struct.unpack('i', data[index:index+4])[0] 45 index += 4 46 vals[start_row + read_rows] = (data[index:index+str_length].decode("utf-8"), "formula group length %i"% formula_group_size) 47 read_rows += formula_group_size 48 index += str_length 49 50 return index, data_size, vals 51 52 53def parse_column(data, index): 54 column_index = struct.unpack('Q', data[index:index+8])[0] 55 index += 8 56 column_entries = struct.unpack('Q', data[index:index+8])[0] 57 index += 8 58 imported_columns = 0 59 column_values = {} 60 while imported_columns < column_entries: 61 index, block_size, vals = parse_block(data, index) 62 imported_columns += block_size 63 column_values.update(vals) 64 return index, column_values 65 66def parse_columns(data, index): 67 column_count = struct.unpack('Q', data[index:index+8])[0] 68 index += 8 69 columns = {} 70 for i in range(column_count): 71 index, column_values = parse_column(data, index) 72 columns[i] = column_values 73 74 return columns 75 76def main(): 77 filename = sys.argv[1] 78 with open(filename, "rb") as f: 79 content = f.read() 80 index = 0 81 columns = parse_columns(content, index) 82 print(columns) 83 84if __name__ == "__main__": 85 main() 86 87# vim:set shiftwidth=4 softtabstop=4 expandtab: */ 88