def read(f, context): propset_header = read_type(MSOLEPropertySetHeader, context, f) common_prop_names = { 0: 'Dictionary', 1: 'CodePage', 2: 'Title', 3: 'Subject', 4: 'Author', 5: 'Keywords', 6: 'Comments', 7: 'Template', 8: 'LastSavedBy', 9: 'RevisionNumber', 11: 'LastPrinted', 12: 'CreateTime', 13: 'LastSavedTime', 14: 'NumPages', } for section_desc in propset_header['sections']: f.seek(section_desc['offset']) section_header = read_type(MSOLEPropertySetSectionHeader, context, f) section_desc['properties'] = section_properties = dict() prop_names = dict(common_prop_names) for prop_desc in section_header['properties']: prop_id = prop_desc['id'] logger.debug('property id: %d', prop_id) f.seek(section_desc['offset'] + prop_desc['offset']) if prop_id == 0: namedict = read_type(MSOLEPropertyNameDict, context, f) section_prop_names = dict((name['id'], name['name']) for name in namedict['names']) #prop_names.update(section_prop_names) section_properties[prop_id] = prop = dict(id=prop_id) prop['name'] = prop_names.get(prop_id, 'property-id-%s' % prop_id) prop['value'] = section_prop_names elif prop_id == 1: # code page pass else: prop = read_type(MSOLEProperty, context, f) prop['id'] = prop_id section_properties[prop_id] = prop if prop_id in prop_names: prop['name'] = prop_names[prop_id] else: prop['name'] = 'property-id-%s' % prop_id logger.debug('name: %s', prop['name']) if not prop['type'].is_vector: vt_code = prop['type'].code vt_type = vt_types[vt_code] logger.debug('type: %s', vt_type) value = read_vt_value(vt_type, context, f) if value is not None: prop['value'] = value return propset_header
def to_dict(self): from hwp5.bintype import read_type f = self.open() try: return read_type(FileHeader, dict(), f) finally: f.close()
def read_vt_value(vt_type, context, f): if vt_type == VT_I4: value = read_type(INT32, context, f) logger.debug('value: %s', value) return value elif vt_type == VT_LPWSTR: value = read_type(BSTR, context, f) logger.debug('value: %s', value) return value elif vt_type == VT_FILETIME: lword = read_type(UINT32, context, f) hword = read_type(UINT32, context, f) value = hword << 32 | lword value = FILETIME_to_datetime(value) logger.debug('value: %s', value) return value
def test_read_parse_error(self): class Foo(Struct): def attributes(): yield INT16, 'a' attributes = staticmethod(attributes) stream = BytesIO() record = dict() context = dict(record=record) try: read_type(Foo, context, stream) assert False, 'ParseError expected' except ParseError as e: self.assertEqual(Foo, e.binevents[0][1]['type']) self.assertEqual('a', e.binevents[-1][1]['name']) self.assertEqual(0, e.offset)
def test_read_parse_error(self): from hwp5.dataio import Struct from hwp5.dataio import INT16 from hwp5.dataio import ParseError class Foo(Struct): def attributes(): yield INT16, 'a' attributes = staticmethod(attributes) from StringIO import StringIO stream = StringIO() from hwp5.bintype import read_type record = dict() context = dict(record=record) try: read_type(Foo, context, stream) assert False, 'ParseError expected' except ParseError, e: self.assertEquals(Foo, e.binevents[0][1]['type']) self.assertEquals('a', e.binevents[-1][1]['name']) self.assertEquals(0, e.offset)
def read(f, context): propertyset = read_type(MSOLEPropertySetHeader, context, f) propertyset['clsid'] = uuid_from_bytes_tuple(propertyset['clsid']) for section in propertyset['sections']: section_offset = section.pop('offset') f.seek(section_offset) section['formatid'] = uuid_from_bytes_tuple(section['formatid']) section['properties'] = dict() section_header = read_type(MSOLEPropertySetSectionHeader, context, f) prop_names = dict((p['id'], p['name']) for p in RESERVED_PROPERTIES + SUMMARY_INFORMATION_PROPERTIES) for desc in section_header['properties']: prop_offset = desc['offset'] f.seek(section_offset + prop_offset) prop_id = desc['id'] prop = section['properties'][prop_id] = dict() if prop_id in prop_names: prop['name'] = prop_names[prop_id] if prop_id == globals()['PID_PROPDISPNAMEDICT']: namedict = read_type(MSOLEPropertyNameDict, context, f) names = dict((e['id'], str_from_bytes_tuple(e['name'])) for e in namedict['names']) prop['value'] = names elif prop_id == globals()['PID_CODEPAGE']: pass else: prop.update(read_type(MSOLEProperty, context, f)) vt_code = prop['type'].code vt_type = vt_types[vt_code] prop['value'] = vt_type.read_value(context, f) return propertyset
def read(self, f): f.seek(self.propsetDesc.offset + self.propDesc.offset) context = {} propType = read_type(TypedPropertyValue, context, f) propType = TypedPropertyValue.fromDict(propType) vt_type = vt_types[propType.code] propValue = vt_type.read_value(context, f) return Property( desc=self.propDesc, idLabel=self.idLabel, type=propType, value=propValue, )
def read(self, f): propsetDesc = self.propsetDesc propDesc = self.propDesc idLabel = self.idLabel f.seek(propsetDesc.offset + propDesc.offset) context = {} propType = None propValue = read_type(Dictionary, context, f) propValue = Dictionary.fromDict(propValue) return Property( desc=propDesc, idLabel=idLabel, type=propType, value=propValue, )
def read_value(cls, context, f): lword = read_type(UINT32, context, f) hword = read_type(UINT32, context, f) value = hword << 32 | lword value = FILETIME_to_datetime(value) return value
def read_value(cls, context, f): length = read_type(UINT32, context, f) data = f.read(length * 2) return data.decode('utf-16le')[:-1] # remove null character
def read_value(cls, context, f): return read_type(INT32, context, f)
def read(self, f): context = {} streamHeader = read_type(PropertySetStreamHeader, context, f) streamHeader = PropertySetStreamHeader.fromDict(streamHeader) propertysetList = list() for propsetDesc in streamHeader.propsetDescList: f.seek(propsetDesc.offset) propsetHeader = read_type(PropertySetHeader, context, f) propsetHeader = PropertySetHeader.fromDict( propsetHeader, ) try: propsetFormat = self.propertySetFormats[propsetDesc.fmtid] except KeyError: idLabels = {} else: idLabels = propsetFormat.idLabels properties = [] propDescMap = { propDesc.id: propDesc for propDesc in propsetHeader.propDescList } propDesc = propDescMap.pop(PID_CODEPAGE.id, None) if propDesc is not None: idLabel = idLabels.get(propDesc.id) propReader = PropertyReader( propsetDesc=propsetDesc, propDesc=propDesc, idLabel=idLabel, codepage=None, displayName=None, ) prop = propReader.read(f) properties.append(prop) codepage = prop.value else: codepage = None propDesc = propDescMap.pop(PID_DICTIONARY.id, None) if propDesc is not None: idLabel = idLabels.get(propDesc.id) propReader = DictionaryReader( propsetDesc, propDesc, idLabel, codepage, ) prop = propReader.read(f) properties.append(prop) dictionary = prop.value else: dictionary = None for propDesc in propDescMap.values(): idLabel = idLabels.get(propDesc.id) displayName = dictionary.get(propDesc.id, None) propReader = PropertyReader( propsetDesc=propsetDesc, propDesc=propDesc, idLabel=idLabel, codepage=codepage, displayName=displayName, ) prop = propReader.read(f) properties.append(prop) propertyset = PropertySet( desc=propsetDesc, header=propsetHeader, properties=properties, ) propertysetList.append(propertyset) return PropertySetStream( header=streamHeader, propertysets=propertysetList, )