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