class Blockptr(Struct): __ENDIAN__ = 'little' dvas = array(dva(), length=3) _prop = uint64() logical_size = BitField(_prop, 16, 0) physical_size = BitField(_prop, 16, 16) compression = BitField(_prop, 6, 32, enum=constants.Compression) encryption = BitField(_prop, 1, 38) embedded = BitField(_prop, 1, 39) checksum_type = BitField(_prop, 8, 40, enum=constants.Checksum) object_type = BitField(_prop, 8, 48, enum=constants.ObjectType) level = BitField(_prop, 5, 56) dedup = BitField(_prop, 1, 62) endian = BitField(_prop, 1, 63) pad = padding(length=16) phys_birth = uint64() birth = uint64() fill = uint64() checksum = array(uint64(), 4) def to_embedded(self): raw_blkptr = self.pack() return EmbeddedBlockptr(raw_blkptr)
class DNode(Struct): __ENDIAN__ = 'little' node_type = uint8(enum=constants.ObjectType) indirect_blockshift = uint8() indirect_levels = uint8() num_blockptrs = uint8() bonustype = uint8(enum=constants.ObjectType) checksum_type = uint8(enum=constants.Checksum) compression_type = uint8(enum=constants.Compression) _dnode_flags = uint8() # TODO: dnode flag bitfields used_bytes = BitField(_dnode_flags, 1, 0) userused = BitField(_dnode_flags, 1, 1) spill_blkptr = BitField(_dnode_flags, 1, 3) data_sectors = uint16() bonuslen = uint16() _pad = padding(length=4) max_block_id = uint64() used = uint64() _pad2 = padding(length=4 * 8) blkptr = array(Blockptr(), length=num_blockptrs) def bonus_length(self, o=None): if self.bonuslen != 0 and self.node_type != constants.ObjectType.NONE: return self.bonuslen elif self.node_type == constants.ObjectType.NONE: return 320 else: return self.bonuslen bonus = bytestring(length=bonus_length) # TODO: finish _final_pad = padding(length=64)
class ArrayWithFunctionLength(pyndata.Struct): def __init__(self, *a, **kw): super(ArrayWithFunctionLength, self).__init__(*a, **kw) self.real_length = 3 def length(self, length=None): if length: self.real_length = length else: return self.real_length a = pyndata.array(pyndata.uint8(), length=length)
class DefaultAttrsV1(pyndata.Struct): __ENDIAN__ = 'little' ZPL_ATIME = Timestamp() ZPL_MTIME = Timestamp() ZPL_CTIME = Timestamp() ZPL_CRTIME = Timestamp() ZPL_GEN = pyndata.uint64() ZPL_MODE = Mode() ZPL_SIZE = pyndata.uint64() ZPL_PARENT = pyndata.uint64() ZPL_LINKS = pyndata.uint64() ZPL_XATTR = pyndata.uint64() ZPL_RDEV = pyndata.uint64() ZPL_FLAGS = pyndata.uint64() ZPL_UID = pyndata.uint64() ZPL_GID = pyndata.uint64() padding = pyndata.array(pyndata.uint64(), length=4) acl = ZNodeACL()
class GangBlock(Struct): MAGIC = 0x210da7ab10c7a11 blocks = array(Blockptr(), length=3) _pad = padding(length=88) magic = uint64() checksum = array(uint64(), 4)
class BPObjHeader(Struct): __ENDIAN__ = 'little' length = uint64() unknown = array(uint16(), length=20)
class IndirectBlock(Struct): __ENDIAN__ = 'little' blocks = array(Blockptr(), length=count)
class ArrayWithBitfieldLength(pyndata.Struct): a = pyndata.uint8() b = pyndata.BitField(a, 8, 0) c = pyndata.array(pyndata.uint8(), length=b)
class FixedArrayTests(pyndata.Struct): arr = pyndata.array(pyndata.uint8(), 3)
class VariableArray(pyndata.Struct): l = pyndata.uint8() a = pyndata.array(pyndata.uint8(), length=l)
class S2(pyndata.Struct): a = pyndata.array(kind=S1(), length=2)
class ZNodeACL(pyndata.Struct): external_object = pyndata.uint64() count = pyndata.uint32() version = pyndata.uint16() _padding = pyndata.padding(length=2) aces = pyndata.array(ZNodeACE, length=count)