two types now

types
Jordan Orelli 8 years ago
parent f1c4db00fb
commit 17dd5d399a

@ -2,15 +2,19 @@ package ent
import ( import (
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
) )
var atom_types = map[string]tÿpe{ var atom_types = map[string]typeFn{
"uint16": {"uint16", func(...interface{}) value { return new(uint16_v) }}, "uint16": func(r bit.Reader) (value, error) {
return uint16(bit.ReadVarInt(r)), r.Err()
},
} }
type uint16_v uint16 func atomType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
var_type := env.symbol(int(flat.GetVarTypeSym()))
func (u *uint16_v) read(r bit.Reader) error { if t, ok := atom_types[var_type]; ok {
*u = uint16_v(bit.ReadVarInt(r)) return t
return r.Err() }
return nil
} }

@ -11,14 +11,13 @@ type field struct {
} }
func (f *field) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) error { func (f *field) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) error {
var_name := env.symbol(int(flat.GetVarNameSym())) Debug.Printf("parse flat field: %s", prettyFlatField(flat, env))
var_type := env.symbol(int(flat.GetVarTypeSym())) t := parseType(flat, env)
if t == nil {
return fmt.Errorf("unable to parse type: %s", prettyFlatField(flat, env))
}
if t, ok := atom_types[var_type]; ok {
f.name = var_name
f.tÿpe = t f.tÿpe = t
f.name = env.symbol(int(flat.GetVarNameSym()))
return nil return nil
}
return fmt.Errorf("unable to parse type: %s", prettyFlatField(flat, env))
} }

@ -0,0 +1,67 @@
package ent
import (
"fmt"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
const (
f_min = 1 << iota
f_max
f_center
)
func qFloatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "CNetworkedQuantizedFloat" {
return nil
}
if flat.GetBitCount() < 0 {
return typeError("quantized float has invalid negative bit count specifier")
}
if flat.GetHighValue()-flat.GetLowValue() < 0 {
return typeError("quantized float has invalid negative range")
}
t := qfloat_t{
bits: uint(flat.GetBitCount()),
low: flat.GetLowValue(),
high: flat.GetHighValue(),
flags: int(flat.GetEncodeFlags()) & 0x7,
}
t.span = t.high - t.low
t.intervals = uint(1<<t.bits - 1)
t.interval = t.span / float32(t.intervals)
if t.flags > 0 {
t.special = new(float32)
}
switch {
case t.flags&f_min > 0:
*t.special = t.low
case t.flags&f_max > 0:
*t.special = t.high
case t.flags&f_center > 0:
*t.special = t.low + (t.high+t.low)*0.5
}
return t
}
type qfloat_t struct {
bits uint
low float32
high float32
flags int
span float32 // total range of values
intervals uint // number of intervals in the quantization range
interval float32 // width of one interval
special *float32
}
func (t qfloat_t) read(r bit.Reader) (value, error) {
if t.special != nil && bit.ReadBool(r) {
return *t.special, nil
}
return nil, fmt.Errorf("I'll get there")
}

@ -1,6 +1,40 @@
package ent package ent
type tÿpe struct { import (
name string "fmt"
alloc func(...interface{}) value
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
type tÿpe interface {
read(bit.Reader) (value, error)
}
type typeFn func(bit.Reader) (value, error)
func (fn typeFn) read(r bit.Reader) (value, error) { return fn(r) }
type typeParseFn func(*dota.ProtoFlattenedSerializerFieldT, *Env) tÿpe
func parseType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
coalesce := func(fns ...typeParseFn) tÿpe {
for _, fn := range fns {
if t := fn(flat, env); t != nil {
return t
}
}
return nil
}
return coalesce(atomType, qFloatType)
}
// 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.
type typeError string
func (e typeError) Error() string { return string(e) }
func (e typeError) read(r bit.Reader) (value, error) {
return nil, fmt.Errorf("type error: %s", string(e))
} }

@ -1,9 +1,3 @@
package ent package ent
import ( type value interface{}
"github.com/jordanorelli/hyperstone/bit"
)
type value interface {
read(bit.Reader) error
}

Loading…
Cancel
Save