package regparser

// Autogenerated code from profile_vtypes.json. Do not edit.

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"sort"
	"strings"
	"unicode/utf16"
	"unicode/utf8"
)

var (
	// Depending on autogenerated code we may use this. Add a reference
	// to shut the compiler up.
	_ = bytes.MinRead
	_ = fmt.Sprintf
	_ = utf16.Decode
	_ = binary.LittleEndian
	_ = utf8.RuneError
	_ = sort.Strings
	_ = strings.Join
	_ = io.Copy
)

func indent(text string) string {
	result := []string{}
	lines := strings.Split(text, "\n")
	for _, line := range lines {
		result = append(result, "  "+line)
	}
	return strings.Join(result, "\n")
}

type RegistryProfile struct {
	Off_HIVE_DIRTY_PAGE_REF_PageOffset       int64
	Off_HIVE_DIRTY_PAGE_REF_PageSize         int64
	Off_HIVE_LOG_ENTRY_Signature             int64
	Off_HIVE_LOG_ENTRY_LogEntrySize          int64
	Off_HIVE_LOG_ENTRY_Flags                 int64
	Off_HIVE_LOG_ENTRY_SequenceNumber        int64
	Off_HIVE_LOG_ENTRY_HiveBinsDataSize      int64
	Off_HIVE_LOG_ENTRY_DirtyPagesCount       int64
	Off_HIVE_LOG_ENTRY_Hash1                 int64
	Off_HIVE_LOG_ENTRY_Hash2                 int64
	Off_HIVE_LOG_ENTRY_DirtyPageRefs         int64
	Off_CHILD_LIST_Count                     int64
	Off_CHILD_LIST_List                      int64
	Off_CM_BIG_DATA_Count                    int64
	Off_CM_BIG_DATA_List                     int64
	Off_CM_BIG_DATA_Signature                int64
	Off_CM_KEY_INDEX_Count                   int64
	Off_CM_KEY_INDEX_List                    int64
	Off_CM_KEY_INDEX_Signature               int64
	Off_CM_KEY_INDEX_FAST_Count              int64
	Off_CM_KEY_INDEX_FAST_List               int64
	Off_CM_KEY_INDEX_FAST_Signature          int64
	Off_CM_KEY_INDEX_FAST_ELEMENT_NodeOffset int64
	Off_CM_KEY_INDEX_FAST_ELEMENT_Index      int64
	Off_CM_KEY_NODE_ChildHiveReference       int64
	Off_CM_KEY_NODE_Class                    int64
	Off_CM_KEY_NODE_ClassLength              int64
	Off_CM_KEY_NODE_Debug                    int64
	Off_CM_KEY_NODE_Flags                    int64
	Off_CM_KEY_NODE_LastWriteTime            int64
	Off_CM_KEY_NODE_MaxClassLen              int64
	Off_CM_KEY_NODE_MaxNameLen               int64
	Off_CM_KEY_NODE_MaxValueDataLen          int64
	Off_CM_KEY_NODE_MaxValueNameLen          int64
	Off_CM_KEY_NODE__Name                    int64
	Off_CM_KEY_NODE_NameLength               int64
	Off_CM_KEY_NODE_Parent                   int64
	Off_CM_KEY_NODE_Security                 int64
	Off_CM_KEY_NODE_Signature                int64
	Off_CM_KEY_NODE_Spare                    int64
	Off_CM_KEY_NODE_SubKeyCounts             int64
	Off_CM_KEY_NODE_SubKeyLists              int64
	Off_CM_KEY_NODE_UserFlags                int64
	Off_CM_KEY_NODE_ValueList                int64
	Off_CM_KEY_NODE_VirtControlFlags         int64
	Off_CM_KEY_NODE_WorkVar                  int64
	Off_CM_KEY_VALUE_Data                    int64
	Off_CM_KEY_VALUE_DataLength              int64
	Off_CM_KEY_VALUE_Flags                   int64
	Off_CM_KEY_VALUE_Name                    int64
	Off_CM_KEY_VALUE_NameLength              int64
	Off_CM_KEY_VALUE_Signature               int64
	Off_CM_KEY_VALUE_Spare                   int64
	Off_CM_KEY_VALUE_Type                    int64
	Off_GUID_Data1                           int64
	Off_GUID_Data2                           int64
	Off_GUID_Data3                           int64
	Off_GUID_Data4                           int64
	Off_HBASE_BLOCK_BootRecover              int64
	Off_HBASE_BLOCK_BootType                 int64
	Off_HBASE_BLOCK_CheckSum                 int64
	Off_HBASE_BLOCK_Cluster                  int64
	Off_HBASE_BLOCK_FileName                 int64
	Off_HBASE_BLOCK_Flags                    int64
	Off_HBASE_BLOCK_Format                   int64
	Off_HBASE_BLOCK_GuidSignature            int64
	Off_HBASE_BLOCK_Length                   int64
	Off_HBASE_BLOCK_LogId                    int64
	Off_HBASE_BLOCK_Major                    int64
	Off_HBASE_BLOCK_Minor                    int64
	Off_HBASE_BLOCK_Reserved1                int64
	Off_HBASE_BLOCK_Reserved2                int64
	Off_HBASE_BLOCK_RmId                     int64
	Off_HBASE_BLOCK_RootCell                 int64
	Off_HBASE_BLOCK_Sequence1                int64
	Off_HBASE_BLOCK_Sequence2                int64
	Off_HBASE_BLOCK_Signature                int64
	Off_HBASE_BLOCK_ThawLogId                int64
	Off_HBASE_BLOCK_ThawRmId                 int64
	Off_HBASE_BLOCK_ThawTmId                 int64
	Off_HBASE_BLOCK_TimeStamp                int64
	Off_HBASE_BLOCK_TmId                     int64
	Off_HBASE_BLOCK_Type                     int64
	Off_HBIN_FileOffset                      int64
	Off_HBIN_Reserved1                       int64
	Off_HBIN_Signature                       int64
	Off_HBIN_HbinSize                        int64
	Off_HBIN_Spare                           int64
	Off_HBIN_TimeStamp                       int64
	Off_HCELL_Next                           int64
	Off_HCELL_Signature                      int64
	Off_HCELL_Data                           int64
	Off_LARGE_INTEGER_HighPart               int64
	Off_LARGE_INTEGER_LowPart                int64
	Off_LARGE_INTEGER_QuadPart               int64
}

func NewRegistryProfile() *RegistryProfile {
	// Specific offsets can be tweaked to cater for slight version mismatches.
	self := &RegistryProfile{0, 4, 0, 4, 8, 12, 16, 20, 24, 32, 40, 0, 4, 2, 4, 0, 2, 4, 0, 2, 4, 0, 0, 4, 28, 48, 74, 52, 2, 4, 56, 52, 64, 60, 76, 72, 16, 44, 0, 12, 20, 28, 52, 36, 52, 68, 8, 4, 16, 20, 2, 0, 18, 12, 0, 4, 6, 8, 4092, 4088, 508, 44, 48, 144, 32, 164, 40, 128, 20, 24, 168, 512, 112, 36, 4, 8, 0, 4072, 4056, 4040, 12, 148, 28, 4, 12, 0, 8, 28, 20, 0, 4, 4, 4, 0, 0}
	return self
}

func (self *RegistryProfile) HIVE_DIRTY_PAGE_REF(reader io.ReaderAt, offset int64) *HIVE_DIRTY_PAGE_REF {
	return &HIVE_DIRTY_PAGE_REF{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) HIVE_LOG_ENTRY(reader io.ReaderAt, offset int64) *HIVE_LOG_ENTRY {
	return &HIVE_LOG_ENTRY{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CHILD_LIST(reader io.ReaderAt, offset int64) *CHILD_LIST {
	return &CHILD_LIST{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CM_BIG_DATA(reader io.ReaderAt, offset int64) *CM_BIG_DATA {
	return &CM_BIG_DATA{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CM_KEY_INDEX(reader io.ReaderAt, offset int64) *CM_KEY_INDEX {
	return &CM_KEY_INDEX{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CM_KEY_INDEX_FAST(reader io.ReaderAt, offset int64) *CM_KEY_INDEX_FAST {
	return &CM_KEY_INDEX_FAST{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CM_KEY_INDEX_FAST_ELEMENT(reader io.ReaderAt, offset int64) *CM_KEY_INDEX_FAST_ELEMENT {
	return &CM_KEY_INDEX_FAST_ELEMENT{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CM_KEY_NODE(reader io.ReaderAt, offset int64) *CM_KEY_NODE {
	return &CM_KEY_NODE{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) CM_KEY_VALUE(reader io.ReaderAt, offset int64) *CM_KEY_VALUE {
	return &CM_KEY_VALUE{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) GUID(reader io.ReaderAt, offset int64) *GUID {
	return &GUID{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) HBASE_BLOCK(reader io.ReaderAt, offset int64) *HBASE_BLOCK {
	return &HBASE_BLOCK{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) HBIN(reader io.ReaderAt, offset int64) *HBIN {
	return &HBIN{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) HCELL(reader io.ReaderAt, offset int64) *HCELL {
	return &HCELL{Reader: reader, Offset: offset, Profile: self}
}

func (self *RegistryProfile) LARGE_INTEGER(reader io.ReaderAt, offset int64) *LARGE_INTEGER {
	return &LARGE_INTEGER{Reader: reader, Offset: offset, Profile: self}
}

type HIVE_DIRTY_PAGE_REF struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *HIVE_DIRTY_PAGE_REF) Size() int {
	return 8
}

func (self *HIVE_DIRTY_PAGE_REF) PageOffset() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_DIRTY_PAGE_REF_PageOffset+self.Offset)
}

func (self *HIVE_DIRTY_PAGE_REF) PageSize() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_DIRTY_PAGE_REF_PageSize+self.Offset)
}

type HIVE_LOG_ENTRY struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *HIVE_LOG_ENTRY) Size() int {
	return 40
}

func (self *HIVE_LOG_ENTRY) Signature() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_Signature+self.Offset)
}

func (self *HIVE_LOG_ENTRY) LogEntrySize() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_LogEntrySize+self.Offset)
}

func (self *HIVE_LOG_ENTRY) Flags() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_Flags+self.Offset)
}

func (self *HIVE_LOG_ENTRY) SequenceNumber() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_SequenceNumber+self.Offset)
}

func (self *HIVE_LOG_ENTRY) HiveBinsDataSize() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_HiveBinsDataSize+self.Offset)
}

func (self *HIVE_LOG_ENTRY) DirtyPagesCount() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_DirtyPagesCount+self.Offset)
}

func (self *HIVE_LOG_ENTRY) Hash1() uint64 {
	return ParseUint64(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_Hash1+self.Offset)
}

func (self *HIVE_LOG_ENTRY) Hash2() uint64 {
	return ParseUint64(self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_Hash2+self.Offset)
}

func (self *HIVE_LOG_ENTRY) DirtyPageRefs() []*HIVE_DIRTY_PAGE_REF {
	return ParseArray_HIVE_DIRTY_PAGE_REF(self.Profile, self.Reader, self.Profile.Off_HIVE_LOG_ENTRY_DirtyPageRefs+self.Offset, int(self.DirtyPagesCount()))
}

type CHILD_LIST struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CHILD_LIST) Size() int {
	return 8
}

func (self *CHILD_LIST) Count() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CHILD_LIST_Count+self.Offset)
}

func (self *CHILD_LIST) List() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CHILD_LIST_List+self.Offset)
}

type CM_BIG_DATA struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CM_BIG_DATA) Size() int {
	return 8
}

func (self *CM_BIG_DATA) Count() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_BIG_DATA_Count+self.Offset)
}

func (self *CM_BIG_DATA) List() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_BIG_DATA_List+self.Offset)
}

func (self *CM_BIG_DATA) Signature() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_BIG_DATA_Signature+self.Offset)
}

type CM_KEY_INDEX struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CM_KEY_INDEX) Size() int {
	return 8
}

func (self *CM_KEY_INDEX) Count() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_INDEX_Count+self.Offset)
}

func (self *CM_KEY_INDEX) List() []uint32 {
	return ParseArray_uint32(self.Profile, self.Reader, self.Profile.Off_CM_KEY_INDEX_List+self.Offset, 1)
}

func (self *CM_KEY_INDEX) Signature() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_INDEX_Signature+self.Offset)
}

type CM_KEY_INDEX_FAST struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CM_KEY_INDEX_FAST) Size() int {
	return 8
}

func (self *CM_KEY_INDEX_FAST) Count() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_INDEX_FAST_Count+self.Offset)
}

func (self *CM_KEY_INDEX_FAST) List() []*CM_KEY_INDEX_FAST_ELEMENT {
	return ParseArray_CM_KEY_INDEX_FAST_ELEMENT(self.Profile, self.Reader, self.Profile.Off_CM_KEY_INDEX_FAST_List+self.Offset, 1)
}

func (self *CM_KEY_INDEX_FAST) Signature() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_INDEX_FAST_Signature+self.Offset)
}

type CM_KEY_INDEX_FAST_ELEMENT struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CM_KEY_INDEX_FAST_ELEMENT) Size() int {
	return 8
}

func (self *CM_KEY_INDEX_FAST_ELEMENT) NodeOffset() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_INDEX_FAST_ELEMENT_NodeOffset+self.Offset)
}

func (self *CM_KEY_INDEX_FAST_ELEMENT) Index() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_INDEX_FAST_ELEMENT_Index+self.Offset)
}

type CM_KEY_NODE struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CM_KEY_NODE) Size() int {
	return 80
}

func (self *CM_KEY_NODE) ChildHiveReference() *HCELL {
	deref := ParseUint64(self.Reader, self.Profile.Off_CM_KEY_NODE_ChildHiveReference+self.Offset)
	return self.Profile.HCELL(self.Reader, int64(deref))
}

func (self *CM_KEY_NODE) Class() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_Class+self.Offset)
}

func (self *CM_KEY_NODE) ClassLength() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_NODE_ClassLength+self.Offset)
}

func (self *CM_KEY_NODE) Debug() uint64 {
	value := ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_Debug+self.Offset)
	return (uint64(value) & 0xffffffff) >> 0x18
}

func (self *CM_KEY_NODE) Flags() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_NODE_Flags+self.Offset)
}

func (self *CM_KEY_NODE) LastWriteTime() *FileTime {
	return self.Profile.FileTime(self.Reader, self.Profile.Off_CM_KEY_NODE_LastWriteTime+self.Offset)
}

func (self *CM_KEY_NODE) MaxClassLen() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_MaxClassLen+self.Offset)
}

func (self *CM_KEY_NODE) MaxNameLen() uint64 {
	value := ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_MaxNameLen+self.Offset)
	return (uint64(value) & 0xffff) >> 0x0
}

func (self *CM_KEY_NODE) MaxValueDataLen() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_MaxValueDataLen+self.Offset)
}

func (self *CM_KEY_NODE) MaxValueNameLen() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_MaxValueNameLen+self.Offset)
}

func (self *CM_KEY_NODE) _Name() []byte {
	return ParseArray_byte(self.Profile, self.Reader, self.Profile.Off_CM_KEY_NODE__Name+self.Offset, 1)
}

func (self *CM_KEY_NODE) NameLength() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_NODE_NameLength+self.Offset)
}

func (self *CM_KEY_NODE) Parent() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_Parent+self.Offset)
}

func (self *CM_KEY_NODE) Security() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_Security+self.Offset)
}

func (self *CM_KEY_NODE) Signature() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_NODE_Signature+self.Offset)
}

func (self *CM_KEY_NODE) Spare() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_Spare+self.Offset)
}

func (self *CM_KEY_NODE) SubKeyCounts() []uint32 {
	return ParseArray_uint32(self.Profile, self.Reader, self.Profile.Off_CM_KEY_NODE_SubKeyCounts+self.Offset, 2)
}

func (self *CM_KEY_NODE) SubKeyLists() []uint32 {
	return ParseArray_uint32(self.Profile, self.Reader, self.Profile.Off_CM_KEY_NODE_SubKeyLists+self.Offset, 2)
}

func (self *CM_KEY_NODE) UserFlags() uint64 {
	value := ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_UserFlags+self.Offset)
	return (uint64(value) & 0xfffff) >> 0x10
}

func (self *CM_KEY_NODE) ValueList() *CHILD_LIST {
	return self.Profile.CHILD_LIST(self.Reader, self.Profile.Off_CM_KEY_NODE_ValueList+self.Offset)
}

func (self *CM_KEY_NODE) VirtControlFlags() uint64 {
	value := ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_VirtControlFlags+self.Offset)
	return (uint64(value) & 0xffffff) >> 0x14
}

func (self *CM_KEY_NODE) WorkVar() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_NODE_WorkVar+self.Offset)
}

type CM_KEY_VALUE struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *CM_KEY_VALUE) Size() int {
	return 24
}

func (self *CM_KEY_VALUE) Data() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_VALUE_Data+self.Offset)
}

func (self *CM_KEY_VALUE) DataLength() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_VALUE_DataLength+self.Offset)
}

func (self *CM_KEY_VALUE) Flags() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_VALUE_Flags+self.Offset)
}

func (self *CM_KEY_VALUE) Name() string {
	return ParseUTF16String(self.Reader, self.Profile.Off_CM_KEY_VALUE_Name+self.Offset, 1)
}

func (self *CM_KEY_VALUE) NameLength() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_VALUE_NameLength+self.Offset)
}

func (self *CM_KEY_VALUE) Signature() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_VALUE_Signature+self.Offset)
}

func (self *CM_KEY_VALUE) Spare() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_CM_KEY_VALUE_Spare+self.Offset)
}

func (self *CM_KEY_VALUE) Type() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_CM_KEY_VALUE_Type+self.Offset)
}

type GUID struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *GUID) Size() int {
	return 16
}

func (self *GUID) Data1() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_GUID_Data1+self.Offset)
}

func (self *GUID) Data2() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_GUID_Data2+self.Offset)
}

func (self *GUID) Data3() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_GUID_Data3+self.Offset)
}

func (self *GUID) Data4() []byte {
	return ParseArray_byte(self.Profile, self.Reader, self.Profile.Off_GUID_Data4+self.Offset, 8)
}

type HBASE_BLOCK struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *HBASE_BLOCK) Size() int {
	return 4096
}

func (self *HBASE_BLOCK) BootRecover() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_BootRecover+self.Offset)
}

func (self *HBASE_BLOCK) BootType() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_BootType+self.Offset)
}

func (self *HBASE_BLOCK) CheckSum() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_CheckSum+self.Offset)
}

func (self *HBASE_BLOCK) Cluster() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Cluster+self.Offset)
}

func (self *HBASE_BLOCK) FileName() string {
	return ParseUTF16String(self.Reader, self.Profile.Off_HBASE_BLOCK_FileName+self.Offset, 64)
}

func (self *HBASE_BLOCK) Flags() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Flags+self.Offset)
}

func (self *HBASE_BLOCK) Format() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Format+self.Offset)
}

func (self *HBASE_BLOCK) GuidSignature() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_GuidSignature+self.Offset)
}

func (self *HBASE_BLOCK) Length() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Length+self.Offset)
}

func (self *HBASE_BLOCK) LogId() *GUID {
	return self.Profile.GUID(self.Reader, self.Profile.Off_HBASE_BLOCK_LogId+self.Offset)
}

func (self *HBASE_BLOCK) Major() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Major+self.Offset)
}

func (self *HBASE_BLOCK) Minor() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Minor+self.Offset)
}

func (self *HBASE_BLOCK) Reserved1() []uint32 {
	return ParseArray_uint32(self.Profile, self.Reader, self.Profile.Off_HBASE_BLOCK_Reserved1+self.Offset, 85)
}

func (self *HBASE_BLOCK) Reserved2() []uint32 {
	return ParseArray_uint32(self.Profile, self.Reader, self.Profile.Off_HBASE_BLOCK_Reserved2+self.Offset, 882)
}

func (self *HBASE_BLOCK) RmId() *GUID {
	return self.Profile.GUID(self.Reader, self.Profile.Off_HBASE_BLOCK_RmId+self.Offset)
}

func (self *HBASE_BLOCK) RootCell() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_RootCell+self.Offset)
}

func (self *HBASE_BLOCK) Sequence1() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Sequence1+self.Offset)
}

func (self *HBASE_BLOCK) Sequence2() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Sequence2+self.Offset)
}

func (self *HBASE_BLOCK) Signature() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Signature+self.Offset)
}

func (self *HBASE_BLOCK) ThawLogId() *GUID {
	return self.Profile.GUID(self.Reader, self.Profile.Off_HBASE_BLOCK_ThawLogId+self.Offset)
}

func (self *HBASE_BLOCK) ThawRmId() *GUID {
	return self.Profile.GUID(self.Reader, self.Profile.Off_HBASE_BLOCK_ThawRmId+self.Offset)
}

func (self *HBASE_BLOCK) ThawTmId() *GUID {
	return self.Profile.GUID(self.Reader, self.Profile.Off_HBASE_BLOCK_ThawTmId+self.Offset)
}

func (self *HBASE_BLOCK) TimeStamp() *FileTime {
	return self.Profile.FileTime(self.Reader, self.Profile.Off_HBASE_BLOCK_TimeStamp+self.Offset)
}

func (self *HBASE_BLOCK) TmId() *GUID {
	return self.Profile.GUID(self.Reader, self.Profile.Off_HBASE_BLOCK_TmId+self.Offset)
}

func (self *HBASE_BLOCK) Type() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBASE_BLOCK_Type+self.Offset)
}

type HBIN struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *HBIN) Size() int {
	return 32
}

func (self *HBIN) FileOffset() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBIN_FileOffset+self.Offset)
}

func (self *HBIN) Reserved1() []uint32 {
	return ParseArray_uint32(self.Profile, self.Reader, self.Profile.Off_HBIN_Reserved1+self.Offset, 2)
}

func (self *HBIN) Signature() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBIN_Signature+self.Offset)
}

func (self *HBIN) HbinSize() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBIN_HbinSize+self.Offset)
}

func (self *HBIN) Spare() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HBIN_Spare+self.Offset)
}

func (self *HBIN) TimeStamp() *FileTime {
	return self.Profile.FileTime(self.Reader, self.Profile.Off_HBIN_TimeStamp+self.Offset)
}

type HCELL struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *HCELL) Size() int {
	return 12
}

func (self *HCELL) Next() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_HCELL_Next+self.Offset)
}

func (self *HCELL) Signature() uint16 {
	return ParseUint16(self.Reader, self.Profile.Off_HCELL_Signature+self.Offset)
}

func (self *HCELL) Data() []byte {
	return ParseArray_byte(self.Profile, self.Reader, self.Profile.Off_HCELL_Data+self.Offset, 0)
}

type LARGE_INTEGER struct {
	Reader  io.ReaderAt
	Offset  int64
	Profile *RegistryProfile
}

func (self *LARGE_INTEGER) Size() int {
	return 8
}

func (self *LARGE_INTEGER) HighPart() int32 {
	return ParseInt32(self.Reader, self.Profile.Off_LARGE_INTEGER_HighPart+self.Offset)
}

func (self *LARGE_INTEGER) LowPart() uint32 {
	return ParseUint32(self.Reader, self.Profile.Off_LARGE_INTEGER_LowPart+self.Offset)
}

func (self *LARGE_INTEGER) QuadPart() int64 {
	return ParseInt64(self.Reader, self.Profile.Off_LARGE_INTEGER_QuadPart+self.Offset)
}

func ParseArray_CM_KEY_INDEX_FAST_ELEMENT(profile *RegistryProfile, reader io.ReaderAt, offset int64, count int) []*CM_KEY_INDEX_FAST_ELEMENT {
	result := make([]*CM_KEY_INDEX_FAST_ELEMENT, 0, count)
	for i := 0; i < count; i++ {
		value := profile.CM_KEY_INDEX_FAST_ELEMENT(reader, offset)
		result = append(result, value)
		offset += int64(value.Size())
	}
	return result
}

func ParseArray_HIVE_DIRTY_PAGE_REF(profile *RegistryProfile, reader io.ReaderAt, offset int64, count int) []*HIVE_DIRTY_PAGE_REF {
	result := make([]*HIVE_DIRTY_PAGE_REF, 0, count)
	for i := 0; i < count; i++ {
		value := profile.HIVE_DIRTY_PAGE_REF(reader, offset)
		result = append(result, value)
		offset += int64(value.Size())
	}
	return result
}

func ParseArray_byte(profile *RegistryProfile, reader io.ReaderAt, offset int64, count int) []byte {
	result := make([]byte, 0, count)
	for i := 0; i < count; i++ {
		value := ParseUint8(reader, offset)
		result = append(result, value)
		offset += int64(1)
	}
	return result
}

func ParseArray_uint32(profile *RegistryProfile, reader io.ReaderAt, offset int64, count int) []uint32 {
	result := make([]uint32, 0, count)
	for i := 0; i < count; i++ {
		value := ParseUint32(reader, offset)
		result = append(result, value)
		offset += int64(4)
	}
	return result
}

func ParseInt32(reader io.ReaderAt, offset int64) int32 {
	var buf [4]byte
	data := buf[:]
	_, err := reader.ReadAt(data, offset)
	if err != nil {
		return 0
	}
	return int32(binary.LittleEndian.Uint32(data))
}

func ParseInt64(reader io.ReaderAt, offset int64) int64 {
	var buf [8]byte
	data := buf[:]
	_, err := reader.ReadAt(data, offset)
	if err != nil {
		return 0
	}
	return int64(binary.LittleEndian.Uint64(data))
}

func ParseUint16(reader io.ReaderAt, offset int64) uint16 {
	var buf [2]byte
	data := buf[:]
	_, err := reader.ReadAt(data, offset)
	if err != nil {
		return 0
	}
	return binary.LittleEndian.Uint16(data)
}

func ParseUint32(reader io.ReaderAt, offset int64) uint32 {
	var buf [4]byte
	data := buf[:]
	_, err := reader.ReadAt(data, offset)
	if err != nil {
		return 0
	}
	return binary.LittleEndian.Uint32(data)
}

func ParseUint64(reader io.ReaderAt, offset int64) uint64 {
	var buf [8]byte
	data := buf[:]
	_, err := reader.ReadAt(data, offset)
	if err != nil {
		return 0
	}
	return binary.LittleEndian.Uint64(data)
}

func ParseUint8(reader io.ReaderAt, offset int64) byte {
	var buf [1]byte
	data := buf[:]
	_, err := reader.ReadAt(data, offset)
	if err != nil {
		return 0
	}
	return data[0]
}

func ParseTerminatedUTF16String(reader io.ReaderAt, offset int64) string {
	var buf [1024]byte
	data := buf[:]
	n, err := reader.ReadAt(data, offset)
	if err != nil && err != io.EOF {
		return ""
	}

	idx := bytes.Index(data[:n], []byte{0, 0})
	if idx < 0 {
		idx = n - 1
	}
	if idx%2 != 0 {
		idx += 1
	}
	return UTF16BytesToUTF8(data[0:idx], binary.LittleEndian)
}

func ParseUTF16String(reader io.ReaderAt, offset int64, length int64) string {
	data := make([]byte, length)
	n, err := reader.ReadAt(data, offset)
	if err != nil && err != io.EOF {
		return ""
	}
	return UTF16BytesToUTF8(data[:n], binary.LittleEndian)
}

func UTF16BytesToUTF8(b []byte, o binary.ByteOrder) string {
	if len(b) < 2 {
		return ""
	}

	if b[0] == 0xff && b[1] == 0xfe {
		o = binary.BigEndian
		b = b[2:]
	} else if b[0] == 0xfe && b[1] == 0xff {
		o = binary.LittleEndian
		b = b[2:]
	}

	utf := make([]uint16, (len(b)+(2-1))/2)

	for i := 0; i+(2-1) < len(b); i += 2 {
		utf[i/2] = o.Uint16(b[i:])
	}
	if len(b)/2 < len(utf) {
		utf[len(utf)-1] = utf8.RuneError
	}

	return string(utf16.Decode(utf))
}
