123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- 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<ppos; i++ {
- bbi, err := strconv.ParseInt(string(data[i:i+1]), 16, 32)
- if err != nil {
- panic(err)
- }
- ba := int64(8)
- for j := 1; j <= 4; j++ {
- bitmap[bi] = (bbi & ba) != 0
- ba >>= 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<ppos; i++ {
- bbi, err := strconv.ParseInt(string(data[i:i+1]), 16, 32)
- if err != nil {
- panic(err)
- }
- ba := int64(8)
- for j := 1; j <= 4; j++ {
- bitmap[bi] = (bbi & ba) != 0
- ba >>= 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))
- }
|