////////////////////////////////////////////////////////////////////////////////
// Do not modify!
// Generated by codergen
////////////////////////////////////////////////////////////////////////////////

package memory

import (
	"fmt"

	"android.googlesource.com/platform/tools/gpu/binary"
	"android.googlesource.com/platform/tools/gpu/binary/registry"
	"android.googlesource.com/platform/tools/gpu/binary/schema"
)

var Namespace = registry.NewNamespace()

func init() {
	registry.Global.AddFallbacks(Namespace)
	Namespace.Add((*Pointer)(nil).Class())
	Namespace.Add((*Range)(nil).Class())
}

var (
	binaryIDPointer = binary.ID{0x32, 0x91, 0x20, 0x2c, 0x71, 0x1c, 0x99, 0xd3, 0xde, 0xad, 0xd6, 0xab, 0xac, 0x67, 0x78, 0xad, 0xfd, 0xb5, 0x05, 0xf9}
	binaryIDRange   = binary.ID{0x4d, 0x08, 0x43, 0xb3, 0xb7, 0x7d, 0x8c, 0x7b, 0x5f, 0x7f, 0x54, 0xb7, 0x7b, 0xa3, 0xd6, 0x55, 0x77, 0x01, 0x52, 0x2c}
)

type binaryClassPointer struct{}

func (*Pointer) Class() binary.Class {
	return (*binaryClassPointer)(nil)
}
func doEncodePointer(e binary.Encoder, o *Pointer) error {
	if err := e.Uint64(o.Address); err != nil {
		return err
	}
	if err := e.Uint32(uint32(o.Pool)); err != nil {
		return err
	}
	return nil
}
func doDecodePointer(d binary.Decoder, o *Pointer) error {
	if obj, err := d.Uint64(); err != nil {
		return err
	} else {
		o.Address = uint64(obj)
	}
	if obj, err := d.Uint32(); err != nil {
		return err
	} else {
		o.Pool = PoolID(obj)
	}
	return nil
}
func doSkipPointer(d binary.Decoder) error {
	if _, err := d.Uint64(); err != nil {
		return err
	}
	if _, err := d.Uint32(); err != nil {
		return err
	}
	return nil
}
func (*binaryClassPointer) ID() binary.ID      { return binaryIDPointer }
func (*binaryClassPointer) New() binary.Object { return &Pointer{} }
func (*binaryClassPointer) Encode(e binary.Encoder, obj binary.Object) error {
	return doEncodePointer(e, obj.(*Pointer))
}
func (*binaryClassPointer) Decode(d binary.Decoder) (binary.Object, error) {
	obj := &Pointer{}
	return obj, doDecodePointer(d, obj)
}
func (*binaryClassPointer) DecodeTo(d binary.Decoder, obj binary.Object) error {
	return doDecodePointer(d, obj.(*Pointer))
}
func (*binaryClassPointer) Skip(d binary.Decoder) error { return doSkipPointer(d) }
func (*binaryClassPointer) Schema() *schema.Class       { return schemaPointer }

var schemaPointer = &schema.Class{
	TypeID:  binaryIDPointer,
	Package: "memory",
	Name:    "Pointer",
	Fields: []schema.Field{
		{Declared: "Address", Type: &schema.Primitive{Name: "uint64", Method: schema.Uint64}},
		{Declared: "Pool", Type: &schema.Primitive{Name: "PoolID", Method: schema.Uint32}},
	},
}

type binaryClassRange struct{}

func (*Range) Class() binary.Class {
	return (*binaryClassRange)(nil)
}
func doEncodeRange(e binary.Encoder, o *Range) error {
	if err := e.Uint64(o.Base); err != nil {
		return err
	}
	if err := e.Uint64(o.Size); err != nil {
		return err
	}
	return nil
}
func doDecodeRange(d binary.Decoder, o *Range) error {
	if obj, err := d.Uint64(); err != nil {
		return err
	} else {
		o.Base = uint64(obj)
	}
	if obj, err := d.Uint64(); err != nil {
		return err
	} else {
		o.Size = uint64(obj)
	}
	return nil
}
func doSkipRange(d binary.Decoder) error {
	if _, err := d.Uint64(); err != nil {
		return err
	}
	if _, err := d.Uint64(); err != nil {
		return err
	}
	return nil
}
func (*binaryClassRange) ID() binary.ID      { return binaryIDRange }
func (*binaryClassRange) New() binary.Object { return &Range{} }
func (*binaryClassRange) Encode(e binary.Encoder, obj binary.Object) error {
	return doEncodeRange(e, obj.(*Range))
}
func (*binaryClassRange) Decode(d binary.Decoder) (binary.Object, error) {
	obj := &Range{}
	return obj, doDecodeRange(d, obj)
}
func (*binaryClassRange) DecodeTo(d binary.Decoder, obj binary.Object) error {
	return doDecodeRange(d, obj.(*Range))
}
func (*binaryClassRange) Skip(d binary.Decoder) error { return doSkipRange(d) }
func (*binaryClassRange) Schema() *schema.Class       { return schemaRange }

var schemaRange = &schema.Class{
	TypeID:  binaryIDRange,
	Package: "memory",
	Name:    "Range",
	Fields: []schema.Field{
		{Declared: "Base", Type: &schema.Primitive{Name: "uint64", Method: schema.Uint64}},
		{Declared: "Size", Type: &schema.Primitive{Name: "uint64", Method: schema.Uint64}},
	},
}

var ConstantValues schema.Constants

const _PoolID_name = "ApplicationPool"

var _PoolID_map = map[PoolID]string{}

func init() {
	_PoolID_map[0] = _PoolID_name[0:15]

	ConstantValues = append(ConstantValues, schema.ConstantSet{
		Type: &schema.Primitive{Name: "PoolID", Method: schema.Uint32},
		Entries: []schema.Constant{
			{Name: _PoolID_name[0:15], Value: uint32(0)},
		},
	})
}

func (v PoolID) String() string {
	if s, ok := _PoolID_map[v]; ok {
		return s
	}
	return fmt.Sprintf("PoolID(%d)", v)
}

func (v *PoolID) Parse(s string) error {
	for k, t := range _PoolID_map {
		if s == t {
			*v = k
			return nil
		}
	}
	return fmt.Errorf("%s not in PoolID", s)
}
