def xattrs_from_bytes(bs, offset=0): ''' Decode an XAttrs from some bytes, return the xattrs dictionary. ''' bfr = CornuCopyBuffer.from_bytes(bs) if offset > 0: bfr.skip(offset) xattrs = {} while not bfr.at_eof(): name = BSString.parse_value(bfr) data = BSData.parse_value(bfr) if name in xattrs: warning("repeated name, ignored: %r", name) else: xattrs[name] = data return xattrs
def last(self): ''' The last Archive entry `(when,E)` or `(None,None)`. ''' with Pfx("%s.last", self): try: flags, payload = self.S.do( ArchiveLastRequest(self.archive_name)) except StoreError as e: warning("%s, returning (None, None)", e) return ArchiveEntry(None, None) found = flags & 0x01 if not found: return ArchiveEntry(None, None) bfr = CornuCopyBuffer.from_bytes(payload) entry = ArchiveEntry.from_buffer(bfr) return entry
def selftest(): ''' Run some self tests. ''' # pylint: disable=import-outside-toplevel from cs.buffer import CornuCopyBuffer for n in (0, 1, 2, 3, 16, 17, 127, 128, 129, 32767, 32768, 32769, 65535, 65536, 65537): bs = transcribe_length_encoded_value(n) bfr = CornuCopyBuffer.from_bytes(bs) n2 = get_length_encoded_value(bfr) assert n == n2, "n:%s != n2:%s" % (n, n2) assert bfr.offset == len( bs), "bfr.offset:%s != len(bs):%s" % (bfr.offset, len(bs)) assert bfr.at_eof, "bfr not at EOF" ds, offset = DataSize.from_bytes(bs) assert ds.value == n assert offset == len(bs) bs2 = bytes(ds) assert bs == bs2 ds2 = DataSize(n) bs3 = bytes(ds2) assert bs == bs3
def parse_value(bfr): ''' Decode a Block reference from a buffer. Format is a `BSData` holding this encoded data: BS(flags) 0x01 indirect blockref 0x02 typed: type follows, otherwise BT_HASHCODE 0x04 type flags: per type flags follow type BS(span) [BS(type)] [BS(type_flags)] union { type BT_HASHCODE: hash type BT_RLE: octet-value (repeat span times to get data) type BT_LITERAL: raw-data (span bytes) type BT_SUBBLOCK: suboffset, super block } Even though this is all decodable without the leading length we use a leading length so that future encodings do not prevent parsing any following data. ''' raw_encoding = BSData.parse_value(bfr) blockref_bfr = CornuCopyBuffer.from_bytes(raw_encoding) flags = BSUInt.parse_value(blockref_bfr) is_indirect = bool(flags & F_BLOCK_INDIRECT) is_typed = bool(flags & F_BLOCK_TYPED) has_type_flags = bool(flags & F_BLOCK_TYPE_FLAGS) unknown_flags = flags & ~(F_BLOCK_INDIRECT | F_BLOCK_TYPED | F_BLOCK_TYPE_FLAGS) if unknown_flags: raise ValueError( "unexpected flags value (0x%02x) with unsupported flags=0x%02x" % (flags, unknown_flags)) span = BSUInt.parse_value(blockref_bfr) if is_indirect: # With indirect blocks, the span is of the implied data, not # the referenced block's data. Therefore we build the referenced # block with a span of None and store the span in the indirect # block. ispan = span span = None # block type, default BT_HASHCODE if is_typed: block_type = BlockType(BSUInt.parse_value(blockref_bfr)) else: block_type = BlockType.BT_HASHCODE if has_type_flags: type_flags = BSUInt.parse_value(blockref_bfr) if type_flags: warning("nonzero type_flags: 0x%02x", type_flags) else: type_flags = 0x00 # instantiate type specific block ref if block_type == BlockType.BT_HASHCODE: hashcode = HashCode.from_buffer(blockref_bfr) B = HashCodeBlock(hashcode=hashcode, span=span) elif block_type == BlockType.BT_RLE: octet = blockref_bfr.take(1) B = RLEBlock(span, octet) elif block_type == BlockType.BT_LITERAL: data = blockref_bfr.take(span) B = LiteralBlock(data) elif block_type == BlockType.BT_SUBBLOCK: suboffset = BSUInt.parse_value(blockref_bfr) superB = BlockRecord.parse_value(blockref_bfr) # wrap inner Block in subspan B = SubBlock(superB, suboffset, span) else: raise ValueError("unsupported Block type 0x%02x" % (block_type, )) if is_indirect: B = IndirectBlock(B, span=ispan) if not blockref_bfr.at_eof(): warning("unparsed data (%d bytes) follow Block %s", len(raw_encoding) - blockref_bfr.offset, B) assert isinstance(B, _Block) return B