    def read_properties(self):
        stream = self.dir.get('properties')
        if stream is None:
            return

        s = stream.open()

        # read the whole stream
        f = BytesIO(s.read())

        (byte_order, version, entry_count) = P_HEADER_STRUCT.unpack(f.read(4))

        if byte_order != 0x4c:
            raise NotImplementedError("be byteorder")

        props = array.array(str('H'))
        if hasattr(props, 'frombytes'):
            props.frombytes(f.read(6 * entry_count))
        else:
            props.fromstring(f.read(6 * entry_count))

        if sys.byteorder == 'big':
            props.byteswap()

        for i in range(entry_count):
            index = i * 3
            pid = props[index + 0]
            format = props[index + 1]
            byte_size = props[index + 2]

            data = f.read(byte_size)
            p = property_formats[format](self, pid, format, version)
            p.data = data
            self.property_entries[pid] = p

        for p in self.property_entries.values():
            p.decode()
            if isinstance(p, (properties.StrongRefSetProperty,
                              properties.StrongRefVectorProperty,
                              properties.WeakRefArrayProperty)):
                p.read_index()