Apple macOS '.DS_Store' file format.
This page hosts a formal specification of macOS '.DS_Store' format using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.
import (
"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
"bytes"
"io"
"golang.org/x/text/encoding/unicode"
)
/**
* Apple macOS '.DS_Store' file format.
* @see <a href="https://en.wikipedia.org/wiki/.DS_Store">Source</a>
* @see <a href="https://metacpan.org/dist/Mac-Finder-DSStore/view/DSStoreFormat.pod">Source</a>
* @see <a href="https://0day.work/parsing-the-ds_store-file-format/">Source</a>
*/
type DsStore struct {
AlignmentHeader []byte
BuddyAllocatorHeader *DsStore_BuddyAllocatorHeader
_io *kaitai.Stream
_root *DsStore
_parent kaitai.Struct
_raw_buddyAllocatorBody []byte
_f_blockAddressMask bool
blockAddressMask int8
_f_buddyAllocatorBody bool
buddyAllocatorBody *DsStore_BuddyAllocatorBody
}
func NewDsStore() *DsStore {
return &DsStore{
}
}
func (this DsStore) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore) Read(io *kaitai.Stream, parent kaitai.Struct, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp1, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp1 = tmp1
this.AlignmentHeader = tmp1
if !(bytes.Equal(this.AlignmentHeader, []uint8{0, 0, 0, 1})) {
return kaitai.NewValidationNotEqualError([]uint8{0, 0, 0, 1}, this.AlignmentHeader, this._io, "/seq/0")
}
tmp2 := NewDsStore_BuddyAllocatorHeader()
err = tmp2.Read(this._io, this, this._root)
if err != nil {
return err
}
this.BuddyAllocatorHeader = tmp2
return err
}
/**
* Bitmask used to calculate the position and the size of each block
* of the B-tree from the block addresses.
*/
func (this *DsStore) BlockAddressMask() (v int8, err error) {
if (this._f_blockAddressMask) {
return this.blockAddressMask, nil
}
this._f_blockAddressMask = true
this.blockAddressMask = int8(31)
return this.blockAddressMask, nil
}
func (this *DsStore) BuddyAllocatorBody() (v *DsStore_BuddyAllocatorBody, err error) {
if (this._f_buddyAllocatorBody) {
return this.buddyAllocatorBody, nil
}
this._f_buddyAllocatorBody = true
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(this.BuddyAllocatorHeader.OfsBookkeepingInfoBlock + 4), io.SeekStart)
if err != nil {
return nil, err
}
tmp3, err := this._io.ReadBytes(int(this.BuddyAllocatorHeader.LenBookkeepingInfoBlock))
if err != nil {
return nil, err
}
tmp3 = tmp3
this._raw_buddyAllocatorBody = tmp3
_io__raw_buddyAllocatorBody := kaitai.NewStream(bytes.NewReader(this._raw_buddyAllocatorBody))
tmp4 := NewDsStore_BuddyAllocatorBody()
err = tmp4.Read(_io__raw_buddyAllocatorBody, this, this._root)
if err != nil {
return nil, err
}
this.buddyAllocatorBody = tmp4
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.buddyAllocatorBody, nil
}
type DsStore_Block struct {
Mode uint32
Counter uint32
Data []*DsStore_Block_BlockData
_io *kaitai.Stream
_root *DsStore
_parent kaitai.Struct
_f_rightmostBlock bool
rightmostBlock *DsStore_Block
}
func NewDsStore_Block() *DsStore_Block {
return &DsStore_Block{
}
}
func (this DsStore_Block) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_Block) Read(io *kaitai.Stream, parent kaitai.Struct, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp5, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Mode = uint32(tmp5)
tmp6, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Counter = uint32(tmp6)
for i := 0; i < int(this.Counter); i++ {
_ = i
tmp7 := NewDsStore_Block_BlockData(this.Mode)
err = tmp7.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Data = append(this.Data, tmp7)
}
return err
}
/**
* Rightmost child block pointer.
*/
func (this *DsStore_Block) RightmostBlock() (v *DsStore_Block, err error) {
if (this._f_rightmostBlock) {
return this.rightmostBlock, nil
}
this._f_rightmostBlock = true
if (this.Mode > 0) {
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return nil, err
}
tmp8, err := this._root.BuddyAllocatorBody()
if err != nil {
return nil, err
}
tmp9, err := tmp8.BlockAddresses[this.Mode].Offset()
if err != nil {
return nil, err
}
_, err = thisIo.Seek(int64(tmp9), io.SeekStart)
if err != nil {
return nil, err
}
tmp10 := NewDsStore_Block()
err = tmp10.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.rightmostBlock = tmp10
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
}
return this.rightmostBlock, nil
}
/**
* If mode is 0, this is a leaf node, otherwise it is an internal node.
*/
/**
* Number of records or number of block id + record pairs.
*/
type DsStore_Block_BlockData struct {
BlockId uint32
Record *DsStore_Block_BlockData_Record
Mode uint32
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_Block
_f_block bool
block *DsStore_Block
}
func NewDsStore_Block_BlockData(mode uint32) *DsStore_Block_BlockData {
return &DsStore_Block_BlockData{
Mode: mode,
}
}
func (this DsStore_Block_BlockData) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_Block_BlockData) Read(io *kaitai.Stream, parent *DsStore_Block, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
if (this.Mode > 0) {
tmp11, err := this._io.ReadU4be()
if err != nil {
return err
}
this.BlockId = uint32(tmp11)
}
tmp12 := NewDsStore_Block_BlockData_Record()
err = tmp12.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Record = tmp12
return err
}
func (this *DsStore_Block_BlockData) Block() (v *DsStore_Block, err error) {
if (this._f_block) {
return this.block, nil
}
this._f_block = true
if (this.Mode > 0) {
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return nil, err
}
tmp13, err := this._root.BuddyAllocatorBody()
if err != nil {
return nil, err
}
tmp14, err := tmp13.BlockAddresses[uint32(this.BlockId)].Offset()
if err != nil {
return nil, err
}
_, err = thisIo.Seek(int64(tmp14), io.SeekStart)
if err != nil {
return nil, err
}
tmp15 := NewDsStore_Block()
err = tmp15.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.block = tmp15
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
}
return this.block, nil
}
type DsStore_Block_BlockData_Record struct {
Filename *DsStore_Block_BlockData_Record_Ustr
StructureType *DsStore_Block_BlockData_Record_FourCharCode
DataType string
Value interface{}
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_Block_BlockData
}
func NewDsStore_Block_BlockData_Record() *DsStore_Block_BlockData_Record {
return &DsStore_Block_BlockData_Record{
}
}
func (this DsStore_Block_BlockData_Record) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_Block_BlockData_Record) Read(io *kaitai.Stream, parent *DsStore_Block_BlockData, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp16 := NewDsStore_Block_BlockData_Record_Ustr()
err = tmp16.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Filename = tmp16
tmp17 := NewDsStore_Block_BlockData_Record_FourCharCode()
err = tmp17.Read(this._io, this, this._root)
if err != nil {
return err
}
this.StructureType = tmp17
tmp18, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp18 = tmp18
this.DataType = string(tmp18)
switch (this.DataType) {
case "blob":
tmp19 := NewDsStore_Block_BlockData_Record_RecordBlob()
err = tmp19.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Value = tmp19
case "bool":
tmp20, err := this._io.ReadU1()
if err != nil {
return err
}
this.Value = tmp20
case "comp":
tmp21, err := this._io.ReadU8be()
if err != nil {
return err
}
this.Value = tmp21
case "dutc":
tmp22, err := this._io.ReadU8be()
if err != nil {
return err
}
this.Value = tmp22
case "long":
tmp23, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Value = tmp23
case "shor":
tmp24, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Value = tmp24
case "type":
tmp25 := NewDsStore_Block_BlockData_Record_FourCharCode()
err = tmp25.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Value = tmp25
case "ustr":
tmp26 := NewDsStore_Block_BlockData_Record_Ustr()
err = tmp26.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Value = tmp26
}
return err
}
/**
* Description of the entry's property.
*/
/**
* Data type of the value.
*/
type DsStore_Block_BlockData_Record_FourCharCode struct {
Value string
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_Block_BlockData_Record
}
func NewDsStore_Block_BlockData_Record_FourCharCode() *DsStore_Block_BlockData_Record_FourCharCode {
return &DsStore_Block_BlockData_Record_FourCharCode{
}
}
func (this DsStore_Block_BlockData_Record_FourCharCode) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_Block_BlockData_Record_FourCharCode) Read(io *kaitai.Stream, parent *DsStore_Block_BlockData_Record, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp27, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp27 = tmp27
this.Value = string(tmp27)
return err
}
type DsStore_Block_BlockData_Record_RecordBlob struct {
Length uint32
Value []byte
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_Block_BlockData_Record
}
func NewDsStore_Block_BlockData_Record_RecordBlob() *DsStore_Block_BlockData_Record_RecordBlob {
return &DsStore_Block_BlockData_Record_RecordBlob{
}
}
func (this DsStore_Block_BlockData_Record_RecordBlob) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_Block_BlockData_Record_RecordBlob) Read(io *kaitai.Stream, parent *DsStore_Block_BlockData_Record, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp28, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Length = uint32(tmp28)
tmp29, err := this._io.ReadBytes(int(this.Length))
if err != nil {
return err
}
tmp29 = tmp29
this.Value = tmp29
return err
}
type DsStore_Block_BlockData_Record_Ustr struct {
Length uint32
Value string
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_Block_BlockData_Record
}
func NewDsStore_Block_BlockData_Record_Ustr() *DsStore_Block_BlockData_Record_Ustr {
return &DsStore_Block_BlockData_Record_Ustr{
}
}
func (this DsStore_Block_BlockData_Record_Ustr) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_Block_BlockData_Record_Ustr) Read(io *kaitai.Stream, parent *DsStore_Block_BlockData_Record, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp30, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Length = uint32(tmp30)
tmp31, err := this._io.ReadBytes(int(2 * this.Length))
if err != nil {
return err
}
tmp31 = tmp31
tmp32, err := kaitai.BytesToStr(tmp31, unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM).NewDecoder())
if err != nil {
return err
}
this.Value = tmp32
return err
}
type DsStore_BuddyAllocatorBody struct {
NumBlocks uint32
_unnamed1 []byte
BlockAddresses []*DsStore_BuddyAllocatorBody_BlockDescriptor
NumDirectories uint32
DirectoryEntries []*DsStore_BuddyAllocatorBody_DirectoryEntry
FreeLists []*DsStore_BuddyAllocatorBody_FreeList
_io *kaitai.Stream
_root *DsStore
_parent *DsStore
_f_directories bool
directories []*DsStore_MasterBlockRef
_f_numBlockAddresses bool
numBlockAddresses int
_f_numFreeLists bool
numFreeLists int8
}
func NewDsStore_BuddyAllocatorBody() *DsStore_BuddyAllocatorBody {
return &DsStore_BuddyAllocatorBody{
}
}
func (this DsStore_BuddyAllocatorBody) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_BuddyAllocatorBody) Read(io *kaitai.Stream, parent *DsStore, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp33, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumBlocks = uint32(tmp33)
tmp34, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp34 = tmp34
this._unnamed1 = tmp34
tmp35, err := this.NumBlockAddresses()
if err != nil {
return err
}
for i := 0; i < int(tmp35); i++ {
_ = i
tmp36 := NewDsStore_BuddyAllocatorBody_BlockDescriptor()
err = tmp36.Read(this._io, this, this._root)
if err != nil {
return err
}
this.BlockAddresses = append(this.BlockAddresses, tmp36)
}
tmp37, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumDirectories = uint32(tmp37)
for i := 0; i < int(this.NumDirectories); i++ {
_ = i
tmp38 := NewDsStore_BuddyAllocatorBody_DirectoryEntry()
err = tmp38.Read(this._io, this, this._root)
if err != nil {
return err
}
this.DirectoryEntries = append(this.DirectoryEntries, tmp38)
}
tmp39, err := this.NumFreeLists()
if err != nil {
return err
}
for i := 0; i < int(tmp39); i++ {
_ = i
tmp40 := NewDsStore_BuddyAllocatorBody_FreeList()
err = tmp40.Read(this._io, this, this._root)
if err != nil {
return err
}
this.FreeLists = append(this.FreeLists, tmp40)
}
return err
}
/**
* Master blocks of the different B-trees.
*/
func (this *DsStore_BuddyAllocatorBody) Directories() (v []*DsStore_MasterBlockRef, err error) {
if (this._f_directories) {
return this.directories, nil
}
this._f_directories = true
thisIo := this._root._io
for i := 0; i < int(this.NumDirectories); i++ {
_ = i
tmp41 := NewDsStore_MasterBlockRef(i)
err = tmp41.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.directories = append(this.directories, tmp41)
}
return this.directories, nil
}
func (this *DsStore_BuddyAllocatorBody) NumBlockAddresses() (v int, err error) {
if (this._f_numBlockAddresses) {
return this.numBlockAddresses, nil
}
this._f_numBlockAddresses = true
this.numBlockAddresses = int(256)
return this.numBlockAddresses, nil
}
func (this *DsStore_BuddyAllocatorBody) NumFreeLists() (v int8, err error) {
if (this._f_numFreeLists) {
return this.numFreeLists, nil
}
this._f_numFreeLists = true
this.numFreeLists = int8(32)
return this.numFreeLists, nil
}
/**
* Number of blocks in the allocated-blocks list.
*/
/**
* Unknown field which appears to always be 0.
*/
/**
* Addresses of the different blocks.
*/
/**
* Indicates the number of directory entries.
*/
/**
* Each directory is an independent B-tree.
*/
type DsStore_BuddyAllocatorBody_BlockDescriptor struct {
AddressRaw uint32
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_BuddyAllocatorBody
_f_offset bool
offset int
_f_size bool
size int
}
func NewDsStore_BuddyAllocatorBody_BlockDescriptor() *DsStore_BuddyAllocatorBody_BlockDescriptor {
return &DsStore_BuddyAllocatorBody_BlockDescriptor{
}
}
func (this DsStore_BuddyAllocatorBody_BlockDescriptor) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_BuddyAllocatorBody_BlockDescriptor) Read(io *kaitai.Stream, parent *DsStore_BuddyAllocatorBody, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp42, err := this._io.ReadU4be()
if err != nil {
return err
}
this.AddressRaw = uint32(tmp42)
return err
}
func (this *DsStore_BuddyAllocatorBody_BlockDescriptor) Offset() (v int, err error) {
if (this._f_offset) {
return this.offset, nil
}
this._f_offset = true
tmp43, err := this._root.BlockAddressMask()
if err != nil {
return 0, err
}
this.offset = int(this.AddressRaw & ^(tmp43) + 4)
return this.offset, nil
}
func (this *DsStore_BuddyAllocatorBody_BlockDescriptor) Size() (v int, err error) {
if (this._f_size) {
return this.size, nil
}
this._f_size = true
tmp44, err := this._root.BlockAddressMask()
if err != nil {
return 0, err
}
this.size = int(1 << (this.AddressRaw & tmp44))
return this.size, nil
}
type DsStore_BuddyAllocatorBody_DirectoryEntry struct {
LenName uint8
Name string
BlockId uint32
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_BuddyAllocatorBody
}
func NewDsStore_BuddyAllocatorBody_DirectoryEntry() *DsStore_BuddyAllocatorBody_DirectoryEntry {
return &DsStore_BuddyAllocatorBody_DirectoryEntry{
}
}
func (this DsStore_BuddyAllocatorBody_DirectoryEntry) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_BuddyAllocatorBody_DirectoryEntry) Read(io *kaitai.Stream, parent *DsStore_BuddyAllocatorBody, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp45, err := this._io.ReadU1()
if err != nil {
return err
}
this.LenName = tmp45
tmp46, err := this._io.ReadBytes(int(this.LenName))
if err != nil {
return err
}
tmp46 = tmp46
this.Name = string(tmp46)
tmp47, err := this._io.ReadU4be()
if err != nil {
return err
}
this.BlockId = uint32(tmp47)
return err
}
type DsStore_BuddyAllocatorBody_FreeList struct {
Counter uint32
Offsets []uint32
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_BuddyAllocatorBody
}
func NewDsStore_BuddyAllocatorBody_FreeList() *DsStore_BuddyAllocatorBody_FreeList {
return &DsStore_BuddyAllocatorBody_FreeList{
}
}
func (this DsStore_BuddyAllocatorBody_FreeList) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_BuddyAllocatorBody_FreeList) Read(io *kaitai.Stream, parent *DsStore_BuddyAllocatorBody, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp48, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Counter = uint32(tmp48)
for i := 0; i < int(this.Counter); i++ {
_ = i
tmp49, err := this._io.ReadU4be()
if err != nil {
return err
}
this.Offsets = append(this.Offsets, tmp49)
}
return err
}
type DsStore_BuddyAllocatorHeader struct {
Magic []byte
OfsBookkeepingInfoBlock uint32
LenBookkeepingInfoBlock uint32
CopyOfsBookkeepingInfoBlock uint32
_unnamed4 []byte
_io *kaitai.Stream
_root *DsStore
_parent *DsStore
}
func NewDsStore_BuddyAllocatorHeader() *DsStore_BuddyAllocatorHeader {
return &DsStore_BuddyAllocatorHeader{
}
}
func (this DsStore_BuddyAllocatorHeader) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_BuddyAllocatorHeader) Read(io *kaitai.Stream, parent *DsStore, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp50, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp50 = tmp50
this.Magic = tmp50
if !(bytes.Equal(this.Magic, []uint8{66, 117, 100, 49})) {
return kaitai.NewValidationNotEqualError([]uint8{66, 117, 100, 49}, this.Magic, this._io, "/types/buddy_allocator_header/seq/0")
}
tmp51, err := this._io.ReadU4be()
if err != nil {
return err
}
this.OfsBookkeepingInfoBlock = uint32(tmp51)
tmp52, err := this._io.ReadU4be()
if err != nil {
return err
}
this.LenBookkeepingInfoBlock = uint32(tmp52)
tmp53, err := this._io.ReadU4be()
if err != nil {
return err
}
this.CopyOfsBookkeepingInfoBlock = uint32(tmp53)
tmp54, err := this._io.ReadBytes(int(16))
if err != nil {
return err
}
tmp54 = tmp54
this._unnamed4 = tmp54
return err
}
/**
* Magic number 'Bud1'.
*/
/**
* Needs to match 'offset_bookkeeping_info_block'.
*/
/**
* Unused field which might simply be the unused space at the end of the block,
* since the minimum allocation size is 32 bytes.
*/
type DsStore_MasterBlockRef struct {
Idx uint64
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_BuddyAllocatorBody
_raw_masterBlock []byte
_f_masterBlock bool
masterBlock *DsStore_MasterBlockRef_MasterBlock
}
func NewDsStore_MasterBlockRef(idx uint64) *DsStore_MasterBlockRef {
return &DsStore_MasterBlockRef{
Idx: idx,
}
}
func (this DsStore_MasterBlockRef) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_MasterBlockRef) Read(io *kaitai.Stream, parent *DsStore_BuddyAllocatorBody, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
return err
}
func (this *DsStore_MasterBlockRef) MasterBlock() (v *DsStore_MasterBlockRef_MasterBlock, err error) {
if (this._f_masterBlock) {
return this.masterBlock, nil
}
this._f_masterBlock = true
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
tmp55, err := this._parent.BlockAddresses[this._parent.DirectoryEntries[this.Idx].BlockId].Offset()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(tmp55), io.SeekStart)
if err != nil {
return nil, err
}
tmp56, err := this._parent.BlockAddresses[this._parent.DirectoryEntries[this.Idx].BlockId].Size()
if err != nil {
return nil, err
}
tmp57, err := this._io.ReadBytes(int(tmp56))
if err != nil {
return nil, err
}
tmp57 = tmp57
this._raw_masterBlock = tmp57
_io__raw_masterBlock := kaitai.NewStream(bytes.NewReader(this._raw_masterBlock))
tmp58 := NewDsStore_MasterBlockRef_MasterBlock()
err = tmp58.Read(_io__raw_masterBlock, this, this._root)
if err != nil {
return nil, err
}
this.masterBlock = tmp58
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.masterBlock, nil
}
type DsStore_MasterBlockRef_MasterBlock struct {
BlockId uint32
NumInternalNodes uint32
NumRecords uint32
NumNodes uint32
_unnamed4 uint32
_io *kaitai.Stream
_root *DsStore
_parent *DsStore_MasterBlockRef
_f_rootBlock bool
rootBlock *DsStore_Block
}
func NewDsStore_MasterBlockRef_MasterBlock() *DsStore_MasterBlockRef_MasterBlock {
return &DsStore_MasterBlockRef_MasterBlock{
}
}
func (this DsStore_MasterBlockRef_MasterBlock) IO_() *kaitai.Stream {
return this._io
}
func (this *DsStore_MasterBlockRef_MasterBlock) Read(io *kaitai.Stream, parent *DsStore_MasterBlockRef, root *DsStore) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp59, err := this._io.ReadU4be()
if err != nil {
return err
}
this.BlockId = uint32(tmp59)
tmp60, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumInternalNodes = uint32(tmp60)
tmp61, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumRecords = uint32(tmp61)
tmp62, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumNodes = uint32(tmp62)
tmp63, err := this._io.ReadU4be()
if err != nil {
return err
}
this._unnamed4 = tmp63
return err
}
func (this *DsStore_MasterBlockRef_MasterBlock) RootBlock() (v *DsStore_Block, err error) {
if (this._f_rootBlock) {
return this.rootBlock, nil
}
this._f_rootBlock = true
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return nil, err
}
tmp64, err := this._root.BuddyAllocatorBody()
if err != nil {
return nil, err
}
tmp65, err := tmp64.BlockAddresses[this.BlockId].Offset()
if err != nil {
return nil, err
}
_, err = thisIo.Seek(int64(tmp65), io.SeekStart)
if err != nil {
return nil, err
}
tmp66 := NewDsStore_Block()
err = tmp66.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.rootBlock = tmp66
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.rootBlock, nil
}
/**
* Block number of the B-tree's root node.
*/
/**
* Number of internal node levels.
*/
/**
* Number of records in the tree.
*/
/**
* Number of nodes in the tree.
*/
/**
* Always 0x1000, probably the B-tree node page size.
*/