json-encode.go
func (cdc *Codec) encodeReflectJSONMap(w io.Writer, info *TypeInfo, rv reflect.Value, fopts FieldOptions) (err error) {
	if printLog {
		fmt.Println("(e) encodeReflectJSONMap")
		defer func() {
			fmt.Printf("(e) -> err: %v\n", err)
		}()
	}

	// Part 1.
	err = writeStr(w, `{`)
	if err != nil {
		return
	}
	// Part 2.
	defer func() {
		if err == nil {
			err = writeStr(w, `}`)
		}
	}()

	// Ensure that the map key type is a string.
	if rv.Type().Key().Kind() != reflect.String {
		err = errors.New("encodeReflectJSONMap: map key type must be a string")
		return
	}

	var writeComma = false
	for _, krv := range rv.MapKeys() {
		// Get dereferenced object value and info.
		var vrv, _, isNil = derefPointers(rv.MapIndex(krv))

		// Add a comma if we need to.
		if writeComma {
			err = writeStr(w, `,`)
			if err != nil {
				return
			}
			writeComma = false
		}
		// Write field name.
		err = invokeStdlibJSONMarshal(w, krv.Interface())
		if err != nil {
			return
		}
		// Write colon.
		err = writeStr(w, `:`)
		if err != nil {
			return
		}
		// Write field value.
		if isNil {
			err = writeStr(w, `null`)
		} else {
			var vinfo *TypeInfo
			vinfo, err = cdc.getTypeInfo_wlock(vrv.Type())
			if err != nil {
				return
			}
			err = cdc.encodeReflectJSON(w, vinfo, vrv, fopts) // pass through fopts
		}
		if err != nil {
			return
		}
		writeComma = true
	}
	return

}
func (cdc *Codec) encodeReflectJSONMap(w io.Writer, info *TypeInfo, rv reflect.Value, fopts FieldOptions) (err error) {
	if printLog {
		fmt.Println("(e) encodeReflectJSONMap")
		defer func() {
			fmt.Printf("(e) -> err: %v\n", err)
		}()
	}

	// Part 1.
	err = writeStr(w, `{`)
	if err != nil {
		return
	}
	// Part 2.
	defer func() {
		if err == nil {
			err = writeStr(w, `}`)
		}
	}()

	// Ensure that the map key type is a string.
	if rv.Type().Key().Kind() != reflect.String {
		err = errors.New("encodeReflectJSONMap: map key type must be a string")
		return
	}

	var writeComma = false
	for _, krv := range rv.MapKeys() {
		// Get dereferenced object value and info.
		var vrv, _, isNil = derefPointers(rv.MapIndex(krv))

		// Add a comma if we need to.
		if writeComma {
			err = writeStr(w, `,`)
			if err != nil {
				return
			}
			writeComma = false
		}
		// Write field name.
		err = invokeStdlibJSONMarshal(w, krv.Interface())
		if err != nil {
			return
		}
		// Write colon.
		err = writeStr(w, `:`)
		if err != nil {
			return
		}
		// Write field value.
		if isNil {
			err = writeStr(w, `null`)
		} else {
			var vinfo *TypeInfo
			vinfo, err = cdc.getTypeInfo_wlock(vrv.Type())
			if err != nil {
				return
			}
			err = cdc.encodeReflectJSON(w, vinfo, vrv, fopts) // pass through fopts
		}
		if err != nil {
			return
		}
		writeComma = true
	}
	return

}
// TODO: TEST