10 func is_empty_value(v reflect.Value) bool {
12 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
16 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
18 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
20 case reflect.Float32, reflect.Float64:
22 case reflect.Interface, reflect.Ptr:
33 func (e *encoder) encode(v interface{}) (err error) {
35 if e := recover(); e != nil {
36 if _, ok := e.(runtime.Error); ok {
42 e.reflect_value(reflect.ValueOf(v))
46 type string_values []reflect.Value
48 func (sv string_values) Len() int { return len(sv) }
49 func (sv string_values) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
50 func (sv string_values) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
51 func (sv string_values) get(i int) string { return sv[i].String() }
53 func (e *encoder) reflect_string(s string) {
54 b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10)
60 func (e *encoder) reflect_byte_slice(s []byte) {
61 b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10)
67 func (e *encoder) reflect_value(v reflect.Value) {
79 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
80 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
84 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
85 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
90 e.reflect_string(v.String())
93 for _, ef := range encode_fields(v.Type()) {
94 field_value := v.Field(ef.i)
95 if ef.omit_empty && is_empty_value(field_value) {
99 e.reflect_string(ef.tag)
100 e.reflect_value(field_value)
104 if v.Type().Key().Kind() != reflect.String {
105 panic(&MarshalTypeError{v.Type()})
112 sv := string_values(v.MapKeys())
114 for _, key := range sv {
115 e.reflect_string(key.String())
116 e.reflect_value(v.MapIndex(key))
124 if v.Type().Elem().Kind() == reflect.Uint8 {
126 e.reflect_byte_slice(s)
132 for i, n := 0, v.Len(); i < n; i++ {
133 e.reflect_value(v.Index(i))
136 case reflect.Interface, reflect.Ptr:
140 e.reflect_value(v.Elem())
142 panic(&MarshalTypeError{v.Type()})
146 type encode_field struct {
152 type encode_fields_sort_type []encode_field
154 func (ef encode_fields_sort_type) Len() int { return len(ef) }
155 func (ef encode_fields_sort_type) Swap(i, j int) { ef[i], ef[j] = ef[j], ef[i] }
156 func (ef encode_fields_sort_type) Less(i, j int) bool { return ef[i].tag < ef[j].tag }
159 type_cache_lock sync.RWMutex
160 encode_fields_cache = make(map[reflect.Type][]encode_field)
163 func encode_fields(t reflect.Type) []encode_field {
164 type_cache_lock.RLock()
165 fs, ok := encode_fields_cache[t]
166 type_cache_lock.RUnlock()
171 type_cache_lock.Lock()
172 defer type_cache_lock.Unlock()
173 fs, ok = encode_fields_cache[t]
178 for i, n := 0, t.NumField(); i < n; i++ {
190 tv := f.Tag.Get("bencode")
195 name, opts := parse_tag(tv)
197 ef.omit_empty = opts.contains("omitempty")
201 fss := encode_fields_sort_type(fs)
203 encode_fields_cache[t] = fs