Scott Baker | 8487c5d | 2019-10-18 12:49:46 -0700 | [diff] [blame] | 1 | package ndr |
| 2 | |
| 3 | import ( |
| 4 | "errors" |
| 5 | "fmt" |
| 6 | "reflect" |
| 7 | "strconv" |
| 8 | ) |
| 9 | |
| 10 | // type MyBytes []byte |
| 11 | // implement RawBytes interface |
| 12 | |
| 13 | const ( |
| 14 | sizeMethod = "Size" |
| 15 | ) |
| 16 | |
| 17 | // RawBytes interface should be implemented if reading just a number of bytes from the NDR stream |
| 18 | type RawBytes interface { |
| 19 | Size(interface{}) int |
| 20 | } |
| 21 | |
| 22 | func rawBytesSize(parent reflect.Value, v reflect.Value) (int, error) { |
| 23 | sf := v.MethodByName(sizeMethod) |
| 24 | if !sf.IsValid() { |
| 25 | return 0, fmt.Errorf("could not find a method called %s on the implementation of RawBytes", sizeMethod) |
| 26 | } |
| 27 | in := []reflect.Value{parent} |
| 28 | f := sf.Call(in) |
| 29 | if f[0].Kind() != reflect.Int { |
| 30 | return 0, errors.New("the RawBytes size function did not return an integer") |
| 31 | } |
| 32 | return int(f[0].Int()), nil |
| 33 | } |
| 34 | |
| 35 | func addSizeToTag(parent reflect.Value, v reflect.Value, tag reflect.StructTag) (reflect.StructTag, error) { |
| 36 | size, err := rawBytesSize(parent, v) |
| 37 | if err != nil { |
| 38 | return tag, err |
| 39 | } |
| 40 | ndrTag := parseTags(tag) |
| 41 | ndrTag.Map["size"] = strconv.Itoa(size) |
| 42 | return ndrTag.StructTag(), nil |
| 43 | } |
| 44 | |
| 45 | func (dec *Decoder) readRawBytes(v reflect.Value, tag reflect.StructTag) error { |
| 46 | ndrTag := parseTags(tag) |
| 47 | sizeStr, ok := ndrTag.Map["size"] |
| 48 | if !ok { |
| 49 | return errors.New("size tag not available") |
| 50 | } |
| 51 | size, err := strconv.Atoi(sizeStr) |
| 52 | if err != nil { |
| 53 | return fmt.Errorf("size not valid: %v", err) |
| 54 | } |
| 55 | b, err := dec.readBytes(size) |
| 56 | if err != nil { |
| 57 | return err |
| 58 | } |
| 59 | v.Set(reflect.ValueOf(b).Convert(v.Type())) |
| 60 | return nil |
| 61 | } |