package codex import ( "fmt" "strconv" ) type CodexBitmap struct { id string fields []Codex } func (c *CodexBitmap) init(cfg map[string]interface{}) { if v, ok := cfg["id"].(string); ok { c.id = v } else { panic(fmt.Sprintf("Invalid CodexBitmap.ID %+v", cfg)) } if v, ok := cfg["fields"].([]interface{}); ok { c.fields = make([]Codex, len(v)) for i,f := range v { if fm, ok := f.(map[string]interface{}); ok { c.fields[i] = parseType(fm) } else { panic(fmt.Sprintf("Invalid field %d %+v", i, f)) } } } else { panic(fmt.Sprintf("Invalid CodexBitmap.Fields %+v", cfg)) } } func (c *CodexBitmap) ID() string { return c.id } func (c *CodexBitmap) Decode(data []byte, pos int, value interface{}) (int, error) { ppos := pos + 16 if len(data) < ppos { return pos, fmt.Errorf("incomplete packet %d %d", len(data), ppos) } var err error bi := 0 var bitmap [128]bool for i := pos; i>= 1 bi++ } } if bitmap[0] { ppos1 := ppos ppos = ppos + 16 if len(data) < ppos { return pos, fmt.Errorf("incomplete packet %d %d", len(data), ppos) } for i := ppos1; i>= 1 bi++ } } } for i := 0; i < 127; i++ { if bitmap[i+1] { ppos, err = c.fields[i].Decode(data, ppos, value) if err != nil { return pos, err } } } return ppos, nil } func (c *CodexBitmap) Encode(data []byte, pos int, value interface{}) (int, error) { if vm, ok := value.(map[string]interface{}); ok { ppos := pos var bitmap [128]bool for i, f := range c.fields { bitmap[i+1] = vm[f.ID()] != nil } for i := 64; i<128; i++ { if bitmap[i] { bitmap[0] = true break } } bi := 0 for i := 0; i<16; i++ { b := byte(0) ba := byte(8) for j := 1; j <= 4; j++ { if bitmap[bi] { b |= ba } ba >>= 1 bi += 1 } if b > 9 { data[ppos] = 38 + b } else { data[ppos] = 48 + b } ppos +=1 } if bitmap[0] { for i := 0; i<16; i++ { b := byte(0) ba := byte(8) for j := 1; j <= 4; j++ { if bitmap[bi] { b |= ba } ba >>= 1 bi += 1 } if b > 9 { data[ppos] = 38 + b } else { data[ppos] = 48 + b } ppos +=1 } } var err error for i, f := range c.fields { if bitmap[i+1] { ppos, err = f.Encode(data, ppos, value) if err != nil { return pos, err } } } return ppos, nil } panic(fmt.Sprintf("Invalid value type [%s] %+v", c.id, value)) }