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

package multiplexer

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

func init() {
	registry.Add((*msgCloseChannel)(nil).Class())
	registry.Add((*msgData)(nil).Class())
	registry.Add((*msgOpenChannel)(nil).Class())
}

var (
	binaryIDmsgCloseChannel = binary.ID{0x91, 0x02, 0x58, 0x8a, 0x4e, 0xad, 0x6f, 0xda, 0x71, 0xbf, 0xc3, 0x4c, 0xd1, 0x77, 0xee, 0x5c, 0x1a, 0x56, 0x5b, 0x7c}
	binaryIDmsgData         = binary.ID{0x0e, 0x45, 0xd6, 0x4e, 0x3a, 0xea, 0x25, 0xbd, 0x5a, 0x98, 0x7e, 0x60, 0x3d, 0xd3, 0xfc, 0x40, 0xd1, 0x70, 0x87, 0xb4}
	binaryIDmsgOpenChannel  = binary.ID{0x3c, 0x8b, 0x89, 0x19, 0x27, 0x6e, 0x2d, 0x99, 0x2d, 0xb0, 0x11, 0x4e, 0x31, 0x50, 0x5a, 0xd4, 0x83, 0xf5, 0xdf, 0x7d}
)

type binaryClassmsgCloseChannel struct{}

func (*msgCloseChannel) Class() binary.Class {
	return (*binaryClassmsgCloseChannel)(nil)
}
func doEncodemsgCloseChannel(e binary.Encoder, o *msgCloseChannel) error {
	if err := e.Uint32(uint32(o.channelId)); err != nil {
		return err
	}
	return nil
}
func doDecodemsgCloseChannel(d binary.Decoder, o *msgCloseChannel) error {
	if obj, err := d.Uint32(); err != nil {
		return err
	} else {
		o.channelId = channelId(obj)
	}
	return nil
}
func doSkipmsgCloseChannel(d binary.Decoder) error {
	if _, err := d.Uint32(); err != nil {
		return err
	}
	return nil
}
func (*binaryClassmsgCloseChannel) ID() binary.ID      { return binaryIDmsgCloseChannel }
func (*binaryClassmsgCloseChannel) New() binary.Object { return &msgCloseChannel{} }
func (*binaryClassmsgCloseChannel) Encode(e binary.Encoder, obj binary.Object) error {
	return doEncodemsgCloseChannel(e, obj.(*msgCloseChannel))
}
func (*binaryClassmsgCloseChannel) Decode(d binary.Decoder) (binary.Object, error) {
	obj := &msgCloseChannel{}
	return obj, doDecodemsgCloseChannel(d, obj)
}
func (*binaryClassmsgCloseChannel) DecodeTo(d binary.Decoder, obj binary.Object) error {
	return doDecodemsgCloseChannel(d, obj.(*msgCloseChannel))
}
func (*binaryClassmsgCloseChannel) Skip(d binary.Decoder) error { return doSkipmsgCloseChannel(d) }
func (*binaryClassmsgCloseChannel) Schema() *schema.Class       { return schemamsgCloseChannel }

var schemamsgCloseChannel = &schema.Class{
	TypeID: binaryIDmsgCloseChannel,
	Name:   "msgCloseChannel",
	Fields: []schema.Field{
		{Declared: "channelId", Type: &schema.Primitive{Name: "channelId", Method: schema.Uint32}},
	},
}

type binaryClassmsgData struct{}

func (*msgData) Class() binary.Class {
	return (*binaryClassmsgData)(nil)
}
func doEncodemsgData(e binary.Encoder, o *msgData) error {
	if err := e.Uint32(uint32(o.c)); err != nil {
		return err
	}
	if err := e.Uint32(uint32(len(o.d))); err != nil {
		return err
	}
	if err := e.Data(o.d); err != nil {
		return err
	}
	return nil
}
func doDecodemsgData(d binary.Decoder, o *msgData) error {
	if obj, err := d.Uint32(); err != nil {
		return err
	} else {
		o.c = channelId(obj)
	}
	if count, err := d.Uint32(); err != nil {
		return err
	} else {
		o.d = make([]byte, count)
		if err := d.Data(o.d); err != nil {
			return err
		}
	}
	return nil
}
func doSkipmsgData(d binary.Decoder) error {
	if _, err := d.Uint32(); err != nil {
		return err
	}
	if count, err := d.Uint32(); err != nil {
		return err
	} else {
		if err := d.Skip(count); err != nil {
			return err
		}
	}
	return nil
}
func (*binaryClassmsgData) ID() binary.ID      { return binaryIDmsgData }
func (*binaryClassmsgData) New() binary.Object { return &msgData{} }
func (*binaryClassmsgData) Encode(e binary.Encoder, obj binary.Object) error {
	return doEncodemsgData(e, obj.(*msgData))
}
func (*binaryClassmsgData) Decode(d binary.Decoder) (binary.Object, error) {
	obj := &msgData{}
	return obj, doDecodemsgData(d, obj)
}
func (*binaryClassmsgData) DecodeTo(d binary.Decoder, obj binary.Object) error {
	return doDecodemsgData(d, obj.(*msgData))
}
func (*binaryClassmsgData) Skip(d binary.Decoder) error { return doSkipmsgData(d) }
func (*binaryClassmsgData) Schema() *schema.Class       { return schemamsgData }

var schemamsgData = &schema.Class{
	TypeID: binaryIDmsgData,
	Name:   "msgData",
	Fields: []schema.Field{
		{Declared: "c", Type: &schema.Primitive{Name: "channelId", Method: schema.Uint32}},
		{Declared: "d", Type: &schema.Slice{Alias: "", ValueType: &schema.Primitive{Name: "byte", Method: schema.Uint8}}},
	},
}

type binaryClassmsgOpenChannel struct{}

func (*msgOpenChannel) Class() binary.Class {
	return (*binaryClassmsgOpenChannel)(nil)
}
func doEncodemsgOpenChannel(e binary.Encoder, o *msgOpenChannel) error {
	if err := e.Uint32(uint32(o.channelId)); err != nil {
		return err
	}
	return nil
}
func doDecodemsgOpenChannel(d binary.Decoder, o *msgOpenChannel) error {
	if obj, err := d.Uint32(); err != nil {
		return err
	} else {
		o.channelId = channelId(obj)
	}
	return nil
}
func doSkipmsgOpenChannel(d binary.Decoder) error {
	if _, err := d.Uint32(); err != nil {
		return err
	}
	return nil
}
func (*binaryClassmsgOpenChannel) ID() binary.ID      { return binaryIDmsgOpenChannel }
func (*binaryClassmsgOpenChannel) New() binary.Object { return &msgOpenChannel{} }
func (*binaryClassmsgOpenChannel) Encode(e binary.Encoder, obj binary.Object) error {
	return doEncodemsgOpenChannel(e, obj.(*msgOpenChannel))
}
func (*binaryClassmsgOpenChannel) Decode(d binary.Decoder) (binary.Object, error) {
	obj := &msgOpenChannel{}
	return obj, doDecodemsgOpenChannel(d, obj)
}
func (*binaryClassmsgOpenChannel) DecodeTo(d binary.Decoder, obj binary.Object) error {
	return doDecodemsgOpenChannel(d, obj.(*msgOpenChannel))
}
func (*binaryClassmsgOpenChannel) Skip(d binary.Decoder) error { return doSkipmsgOpenChannel(d) }
func (*binaryClassmsgOpenChannel) Schema() *schema.Class       { return schemamsgOpenChannel }

var schemamsgOpenChannel = &schema.Class{
	TypeID: binaryIDmsgOpenChannel,
	Name:   "msgOpenChannel",
	Fields: []schema.Field{
		{Declared: "channelId", Type: &schema.Primitive{Name: "channelId", Method: schema.Uint32}},
	},
}
