encode_map.go (3467B)
1 package msgpack 2 3 import ( 4 "math" 5 "reflect" 6 "sort" 7 8 "github.com/vmihailenco/msgpack/v5/msgpcode" 9 ) 10 11 func encodeMapValue(e *Encoder, v reflect.Value) error { 12 if v.IsNil() { 13 return e.EncodeNil() 14 } 15 16 if err := e.EncodeMapLen(v.Len()); err != nil { 17 return err 18 } 19 20 iter := v.MapRange() 21 for iter.Next() { 22 if err := e.EncodeValue(iter.Key()); err != nil { 23 return err 24 } 25 if err := e.EncodeValue(iter.Value()); err != nil { 26 return err 27 } 28 } 29 30 return nil 31 } 32 33 func encodeMapStringStringValue(e *Encoder, v reflect.Value) error { 34 if v.IsNil() { 35 return e.EncodeNil() 36 } 37 38 if err := e.EncodeMapLen(v.Len()); err != nil { 39 return err 40 } 41 42 m := v.Convert(mapStringStringType).Interface().(map[string]string) 43 if e.flags&sortMapKeysFlag != 0 { 44 return e.encodeSortedMapStringString(m) 45 } 46 47 for mk, mv := range m { 48 if err := e.EncodeString(mk); err != nil { 49 return err 50 } 51 if err := e.EncodeString(mv); err != nil { 52 return err 53 } 54 } 55 56 return nil 57 } 58 59 func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error { 60 if v.IsNil() { 61 return e.EncodeNil() 62 } 63 m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{}) 64 if e.flags&sortMapKeysFlag != 0 { 65 return e.EncodeMapSorted(m) 66 } 67 return e.EncodeMap(m) 68 } 69 70 func (e *Encoder) EncodeMap(m map[string]interface{}) error { 71 if m == nil { 72 return e.EncodeNil() 73 } 74 if err := e.EncodeMapLen(len(m)); err != nil { 75 return err 76 } 77 for mk, mv := range m { 78 if err := e.EncodeString(mk); err != nil { 79 return err 80 } 81 if err := e.Encode(mv); err != nil { 82 return err 83 } 84 } 85 return nil 86 } 87 88 func (e *Encoder) EncodeMapSorted(m map[string]interface{}) error { 89 if m == nil { 90 return e.EncodeNil() 91 } 92 if err := e.EncodeMapLen(len(m)); err != nil { 93 return err 94 } 95 96 keys := make([]string, 0, len(m)) 97 98 for k := range m { 99 keys = append(keys, k) 100 } 101 102 sort.Strings(keys) 103 104 for _, k := range keys { 105 if err := e.EncodeString(k); err != nil { 106 return err 107 } 108 if err := e.Encode(m[k]); err != nil { 109 return err 110 } 111 } 112 113 return nil 114 } 115 116 func (e *Encoder) encodeSortedMapStringString(m map[string]string) error { 117 keys := make([]string, 0, len(m)) 118 for k := range m { 119 keys = append(keys, k) 120 } 121 sort.Strings(keys) 122 123 for _, k := range keys { 124 err := e.EncodeString(k) 125 if err != nil { 126 return err 127 } 128 if err = e.EncodeString(m[k]); err != nil { 129 return err 130 } 131 } 132 133 return nil 134 } 135 136 func (e *Encoder) EncodeMapLen(l int) error { 137 if l < 16 { 138 return e.writeCode(msgpcode.FixedMapLow | byte(l)) 139 } 140 if l <= math.MaxUint16 { 141 return e.write2(msgpcode.Map16, uint16(l)) 142 } 143 return e.write4(msgpcode.Map32, uint32(l)) 144 } 145 146 func encodeStructValue(e *Encoder, strct reflect.Value) error { 147 structFields := structs.Fields(strct.Type(), e.structTag) 148 if e.flags&arrayEncodedStructsFlag != 0 || structFields.AsArray { 149 return encodeStructValueAsArray(e, strct, structFields.List) 150 } 151 fields := structFields.OmitEmpty(strct, e.flags&omitEmptyFlag != 0) 152 153 if err := e.EncodeMapLen(len(fields)); err != nil { 154 return err 155 } 156 157 for _, f := range fields { 158 if err := e.EncodeString(f.name); err != nil { 159 return err 160 } 161 if err := f.EncodeValue(e, strct); err != nil { 162 return err 163 } 164 } 165 166 return nil 167 } 168 169 func encodeStructValueAsArray(e *Encoder, strct reflect.Value, fields []*field) error { 170 if err := e.EncodeArrayLen(len(fields)); err != nil { 171 return err 172 } 173 for _, f := range fields { 174 if err := f.EncodeValue(e, strct); err != nil { 175 return err 176 } 177 } 178 return nil 179 }