// 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"
)
/**
* This is an unnamed and undocumented partition table format implemented by
* the bootloader and kernel that Amlogic provides for their Linux SoCs (Meson
* series at least, and probably others). They appear to use this rather than GPT,
* the industry standard, because their BootROM loads and executes the next stage
* loader from offset 512 (0x200) on the eMMC, which is exactly where the GPT
* header would have to start. So instead of changing their BootROM, Amlogic
* devised this partition table, which lives at an offset of 36MiB (0x240_0000)
* on the eMMC and so doesn't conflict. This parser expects as input just the
* partition table from that offset. The maximum number of partitions in a table
* is 32, which corresponds to a maximum table size of 1304 bytes (0x518).
* @see Source
* @see Source
*/
type AmlogicEmmcPartitions struct {
Magic []byte
Version string
NumPartitions int32
Checksum uint32
Partitions []*AmlogicEmmcPartitions_Partition
_io *kaitai.Stream
_root *AmlogicEmmcPartitions
_parent interface{}
}
func NewAmlogicEmmcPartitions() *AmlogicEmmcPartitions {
return &AmlogicEmmcPartitions{
}
}
func (this *AmlogicEmmcPartitions) Read(io *kaitai.Stream, parent interface{}, root *AmlogicEmmcPartitions) (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.Magic = tmp1
if !(bytes.Equal(this.Magic, []uint8{77, 80, 84, 0})) {
return kaitai.NewValidationNotEqualError([]uint8{77, 80, 84, 0}, this.Magic, this._io, "/seq/0")
}
tmp2, err := this._io.ReadBytes(int(12))
if err != nil {
return err
}
tmp2 = kaitai.BytesTerminate(tmp2, 0, false)
this.Version = string(tmp2)
tmp3, err := this._io.ReadS4le()
if err != nil {
return err
}
this.NumPartitions = int32(tmp3)
if !(this.NumPartitions >= 1) {
return kaitai.NewValidationLessThanError(1, this.NumPartitions, this._io, "/seq/2")
}
if !(this.NumPartitions <= 32) {
return kaitai.NewValidationGreaterThanError(32, this.NumPartitions, this._io, "/seq/2")
}
tmp4, err := this._io.ReadU4le()
if err != nil {
return err
}
this.Checksum = uint32(tmp4)
for i := 0; i < int(this.NumPartitions); i++ {
_ = i
tmp5 := NewAmlogicEmmcPartitions_Partition()
err = tmp5.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Partitions = append(this.Partitions, tmp5)
}
return err
}
/**
* To calculate this, treat the first (and only the first) partition
* descriptor in the table below as an array of unsigned little-endian
* 32-bit integers. Sum all those integers mod 2^32, then multiply the
* result by the total number of partitions, also mod 2^32. Amlogic
* likely meant to include all the partition descriptors in the sum,
* but their code as written instead repeatedly loops over the first
* one, once for each partition in the table.
*/
type AmlogicEmmcPartitions_Partition struct {
Name string
Size uint64
Offset uint64
Flags *AmlogicEmmcPartitions_Partition_PartFlags
Padding []byte
_io *kaitai.Stream
_root *AmlogicEmmcPartitions
_parent *AmlogicEmmcPartitions
_raw_Flags []byte
}
func NewAmlogicEmmcPartitions_Partition() *AmlogicEmmcPartitions_Partition {
return &AmlogicEmmcPartitions_Partition{
}
}
func (this *AmlogicEmmcPartitions_Partition) Read(io *kaitai.Stream, parent *AmlogicEmmcPartitions, root *AmlogicEmmcPartitions) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp6, err := this._io.ReadBytes(int(16))
if err != nil {
return err
}
tmp6 = kaitai.BytesTerminate(tmp6, 0, false)
this.Name = string(tmp6)
tmp7, err := this._io.ReadU8le()
if err != nil {
return err
}
this.Size = uint64(tmp7)
tmp8, err := this._io.ReadU8le()
if err != nil {
return err
}
this.Offset = uint64(tmp8)
tmp9, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp9 = tmp9
this._raw_Flags = tmp9
_io__raw_Flags := kaitai.NewStream(bytes.NewReader(this._raw_Flags))
tmp10 := NewAmlogicEmmcPartitions_Partition_PartFlags()
err = tmp10.Read(_io__raw_Flags, this, this._root)
if err != nil {
return err
}
this.Flags = tmp10
tmp11, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp11 = tmp11
this.Padding = tmp11
return err
}
/**
* The start of the partition relative to the start of the eMMC, in bytes
*/
type AmlogicEmmcPartitions_Partition_PartFlags struct {
IsCode bool
IsCache bool
IsData bool
_io *kaitai.Stream
_root *AmlogicEmmcPartitions
_parent *AmlogicEmmcPartitions_Partition
}
func NewAmlogicEmmcPartitions_Partition_PartFlags() *AmlogicEmmcPartitions_Partition_PartFlags {
return &AmlogicEmmcPartitions_Partition_PartFlags{
}
}
func (this *AmlogicEmmcPartitions_Partition_PartFlags) Read(io *kaitai.Stream, parent *AmlogicEmmcPartitions_Partition, root *AmlogicEmmcPartitions) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp12, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.IsCode = tmp12 != 0
tmp13, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.IsCache = tmp13 != 0
tmp14, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.IsData = tmp14 != 0
return err
}