You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.1 KiB
Go

package ent
import (
"fmt"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
type tÿpe interface {
nü() value
typeName() string
}
type typeLiteral struct {
name string
newFn func() value
}
func (t typeLiteral) nü() value { return t.newFn() }
func (t typeLiteral) typeName() string { return t.name }
type typeParseFn func(*typeSpec, *Env) tÿpe
func parseFieldType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
spec := new(typeSpec)
spec.fromProto(flat, env)
return parseTypeSpec(spec, env)
}
func parseTypeSpec(spec *typeSpec, env *Env) tÿpe {
Debug.Printf(" parse spec: %v", spec)
coalesce := func(fns ...typeParseFn) tÿpe {
for _, fn := range fns {
if t := fn(spec, env); t != nil {
return t
}
}
return nil
}
return coalesce(arrayType, atomType, floatType, handleType, qAngleType,
hSeqType, genericType, vectorType, classType, unknownType)
}
type unknown_t string
func (t unknown_t) typeName() string { return string(t) }
func (t *unknown_t) nü() value {
return &unknown_v{t: t}
}
type unknown_v struct {
t tÿpe
v uint64
}
func (v unknown_v) tÿpe() tÿpe { return v.t }
func (v *unknown_v) read(r bit.Reader) error {
v.v = bit.ReadVarInt(r)
return r.Err()
}
func (v unknown_v) String() string {
return fmt.Sprintf("%s(unknown):%d", v.t.typeName(), v.v)
}
func unknownType(spec *typeSpec, env *Env) tÿpe {
Debug.Printf("Unknown Type: %v", spec)
t := unknown_t(spec.typeName)
return &t
}
// a type error is both an error and a type. It represents a type that we were
// unable to correctly parse. It can be interpreted as an error or as a type;
// when interpreted as a type, it errors every time it tries to read a value.
func typeError(t string, args ...interface{}) tÿpe {
Debug.Printf(" type error: %s", fmt.Sprintf(t, args...))
return error_t(fmt.Sprintf(t, args...))
}
type error_t string
func (e error_t) nü() value { panic("can't create an error val like that") }
func (e error_t) typeName() string { return "error" }
func (e error_t) Error() string { return string(e) }
type typeSpec struct {
name string
typeName string
bits uint
low float32
high float32
flags int
serializer string
serializerV int
send string
encoder string
}
func (s *typeSpec) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) {
s.name = env.symbol(int(flat.GetVarNameSym()))
s.typeName = env.symbol(int(flat.GetVarTypeSym()))
if flat.GetBitCount() < 0 {
// this would cause ridiculously long reads later if we let it overflow
panic("negative bit count: data is likely corrupt")
}
s.bits = uint(flat.GetBitCount())
s.low = flat.GetLowValue()
s.high = flat.GetHighValue()
s.flags = int(flat.GetEncodeFlags())
if flat.FieldSerializerNameSym != nil {
s.serializer = env.symbol(int(*flat.FieldSerializerNameSym))
}
s.serializerV = int(flat.GetFieldSerializerVersion())
if flat.SendNodeSym != nil {
s.send = env.symbol(int(*flat.SendNodeSym))
}
if flat.VarEncoderSym != nil {
s.encoder = env.symbol(int(*flat.VarEncoderSym))
}
}