--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,151 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import logging
+import __init__
+from hcrplugin.hcrrepository import HcrRecord, HcrRepository
+from struct import pack, unpack
+from hcrplugin.hcr_writer import VALUE_TYPE_MAP,VALUE_TYPES_WITH_LSD,VALUE_TYPES_UNSIGNED_INT
+from hcrplugin.hcr_header import HcrHeader
+from hcrplugin.hcr_exceptions import *
+
+
+class HcrReader(object):
+
+ def parse_repository_from_bindata(self, data):
+ """
+ @return: HcrRepository object constructed from the given binary data.
+ """
+ header_data = data[:32]
+ header = HcrHeader()
+ header.loads(header_data)
+
+ expected_len = 32 + header.nrecords * 20 + header.lsd_size
+ if len(data) < expected_len:
+ raise InvalidHcrDataSizeError("File size is %d, expected at least %d based on header" \
+ % (len(data), expected_len))
+
+ expected_lsd_offset = 32 + header.nrecords * 20
+ if header.lsd_offset != expected_lsd_offset:
+ raise InvalidLsdSectionOffsetError("LSD offset is %d, expected %d" \
+ % (header.lsd_offset, expected_lsd_offset))
+
+ records = []
+ for i in xrange(header.nrecords):
+ record_offset = 32 + i * 20
+ record_data = data[record_offset:record_offset+20]
+ record,lsd_pos = self.parse_record_from_bindata(record_data)
+ if lsd_pos != None:
+ if lsd_pos[0] > header.lsd_size or (lsd_pos[0] + lsd_pos[1]) > header.lsd_size:
+ raise InvalidRecordLsdPositionError(
+ "LSD offset of record %d (category=%d, element=%d) is %r, but LSD section size is %d" \
+ % (i, record.category_id, record.element_id, lsd_pos, header.lsd_size))
+ lsd_offset = lsd_pos[0] + header.lsd_offset
+ lsd_data = data[lsd_offset:lsd_offset+lsd_pos[1]]
+ record.value = self.parse_record_value_from_lsd_bindata(record.type,lsd_data)
+ records.append(record)
+
+ return HcrRepository(records,header.version,header.flags)
+
+ def parse_record_from_bindata(self, data):
+ """
+ @return: Tuple: (record, lsd_pos) where
+ record = HcrRecord object constructed from the given binary data.
+ lsd_pos = The position of the record's data in the LSD section in the
+ form of a tuple (offset, size), or None if the record does
+ not have any data in the LSD section.
+ """
+
+ if len(data) != 20:
+ raise HcrReaderError("Invalid record length: %d, expected 20" % len(data))
+
+ result = unpack("<IIIHH",data[:16])
+
+ category_id = result[0]
+ element_id = result[1]
+ value_type = result[2]
+ flag = result[3]
+ lsd_len = result[4]
+
+
+
+ for key,val in VALUE_TYPE_MAP.iteritems():
+ if val == value_type:
+ value_type = key
+ break
+ if value_type not in VALUE_TYPE_MAP:
+ raise InvalidRecordValueTypeError("Invalid value type:%X" % value_type)
+
+ value = None
+ lsd_pos = None
+ if value_type in VALUE_TYPES_WITH_LSD:
+ lsd_offset = unpack("<I",data[16:])[0]
+ lsd_pos = (lsd_offset,lsd_len)
+ else:
+ if value_type in VALUE_TYPES_UNSIGNED_INT:
+ format = "<I"
+ elif value_type == HcrRecord.VALTYPE_INT8:
+ format = "<bxxx"
+ elif value_type == HcrRecord.VALTYPE_INT16:
+ format = "<hxx"
+ else:
+ format = "<i"
+
+ value = unpack(format, data[16:])[0]
+
+ if value_type == HcrRecord.VALTYPE_BOOL:
+ value = bool(value)
+
+
+
+ record = HcrRecord(value_type,value,category_id,element_id,flag)
+
+ return record,lsd_pos
+
+
+ def parse_record_value_from_lsd_bindata(self, record_type, data):
+ """
+ @return: The record value parsed from the given binary data in the LSD section.
+ @param type: The HCRML type of the record whose LSD data is to be parsed.
+ """
+ if record_type == HcrRecord.VALTYPE_TEXT8:
+ return data.decode("utf-8")
+
+ elif record_type == HcrRecord.VALTYPE_BIN_DATA:
+ return data
+
+ elif record_type == HcrRecord.VALTYPE_ARRAY_INT32:
+ if len(data) % 4 != 0:
+ raise InvalidRecordLsdPositionError("Int32 array requires an amount of LSD data that is divisible by 4 (data with size %d was given)" % len(data))
+ return list(unpack("<%di"%(len(data)/4), data))
+
+ elif record_type == HcrRecord.VALTYPE_ARRAY_UINT32:
+ if len(data) % 4 != 0:
+ raise InvalidRecordLsdPositionError("Uint32 array requires an amount of LSD data that is divisible by 4 (data with size %d was given)" % len(data))
+ return list(unpack("<%dI"%(len(data)/4), data))
+
+ elif record_type == HcrRecord.VALTYPE_INT64:
+ if len(data) != 8:
+ raise InvalidRecordLsdPositionError("Int64 requires LSD data size to be 8 bytes (%d given)" % len(data))
+ return unpack("<q",data)[0]
+
+ elif record_type == HcrRecord.VALTYPE_UINT64:
+ if len(data) != 8:
+ raise InvalidRecordLsdPositionError("Uint64 requires LSD data size to be 8 bytes (%d given)" % len(data))
+ return unpack("<Q",data)[0]
+
+ else:
+ return None