Package jsonutil provides JSON serialization of AWS requests and responses.
package jsonutil

import (
	
	
	
	
	
	
	
	
	

	
	
)

var timeType = reflect.ValueOf(time.Time{}).Type()
var byteSliceType = reflect.ValueOf([]byte{}).Type()
BuildJSON builds a JSON string for a given object v.
func ( interface{}) ([]byte, error) {
	var  bytes.Buffer

	 := buildAny(reflect.ValueOf(), &, "")
	return .Bytes(), 
}

func ( reflect.Value,  *bytes.Buffer,  reflect.StructTag) error {
	 := 
	 = reflect.Indirect()
	if !.IsValid() {
		return nil
	}

	 := .Type()

	 := .Get("type")
	if  == "" {
		switch .Kind() {
also it can't be a time object
			if .Type() != timeType {
				 = "structure"
			}
also it can't be a byte slice
			if ,  := .Interface().([]byte); ! {
				 = "list"
			}
cannot be a JSONValue map
			if ,  := .Interface().(aws.JSONValue); ! {
				 = "map"
			}
		}
	}

	switch  {
	case "structure":
		if ,  := .FieldByName("_");  {
			 = .Tag
		}
		return buildStruct(, , )
	case "list":
		return buildList(, , )
	case "map":
		return buildMap(, , )
	default:
		return buildScalar(, , )
	}
}

func ( reflect.Value,  *bytes.Buffer,  reflect.StructTag) error {
	if !.IsValid() {
		return nil
	}
unwrap payloads
	if  := .Get("payload");  != "" {
		,  := .Type().FieldByName()
		 = .Tag
		 = elemOf(.FieldByName())

		if !.IsValid() {
			return nil
		}
	}

	.WriteByte('{')

	 := .Type()
	 := true
	for  := 0;  < .NumField(); ++ {
		 := .Field()
This allocates the most memory. Additionally, we cannot skip nil fields due to idempotency auto filling.
		 := .Field()

		if .PkgPath != "" {
			continue // ignore unexported fields
		}
		if .Tag.Get("json") == "-" {
			continue
		}
		if .Tag.Get("location") != "" {
			continue // ignore non-body elements
		}
		if .Tag.Get("ignore") != "" {
			continue
		}

		if protocol.CanSetIdempotencyToken(, ) {
			 := protocol.GetIdempotencyToken()
			 = reflect.ValueOf(&)
		}

		if (.Kind() == reflect.Ptr || .Kind() == reflect.Slice || .Kind() == reflect.Map) && .IsNil() {
			continue // ignore unset fields
		}

		if  {
			 = false
		} else {
			.WriteByte(',')
		}
figure out what this field is called
		 := .Name
		if  := .Tag.Get("locationName");  != "" {
			 = 
		}

		writeString(, )
		.WriteString(`:`)

		 := buildAny(, , .Tag)
		if  != nil {
			return 
		}

	}

	.WriteString("}")

	return nil
}

func ( reflect.Value,  *bytes.Buffer,  reflect.StructTag) error {
	.WriteString("[")

	for  := 0;  < .Len(); ++ {
		buildAny(.Index(), , "")

		if  < .Len()-1 {
			.WriteString(",")
		}
	}

	.WriteString("]")

	return nil
}

type sortedValues []reflect.Value

func ( sortedValues) () int           { return len() }
func ( sortedValues) (,  int)      { [], [] = [], [] }
func ( sortedValues) (,  int) bool { return [].String() < [].String() }

func ( reflect.Value,  *bytes.Buffer,  reflect.StructTag) error {
	.WriteString("{")

	 := sortedValues(.MapKeys())
	sort.Sort()

	for ,  := range  {
		if  > 0 {
			.WriteByte(',')
		}

		writeString(.String(), )
		.WriteString(`:`)

		buildAny(.MapIndex(), , "")
	}

	.WriteString("}")

	return nil
}

prevents allocation on the heap.
	 := [64]byte{}
	switch  := reflect.Indirect(); .Kind() {
	case reflect.String:
		writeString(.String(), )
	case reflect.Bool:
		if .Bool() {
			.WriteString("true")
		} else {
			.WriteString("false")
		}
	case reflect.Int64:
		.Write(strconv.AppendInt([:0], .Int(), 10))
	case reflect.Float64:
		 := .Float()
		if math.IsInf(, 0) || math.IsNaN() {
			return &json.UnsupportedValueError{Value: , Str: strconv.FormatFloat(, 'f', -1, 64)}
		}
		.Write(strconv.AppendFloat([:0], , 'f', -1, 64))
	default:
		switch converted := .Interface().(type) {
		case time.Time:
			 := .Get("timestampFormat")
			if len() == 0 {
				 = protocol.UnixTimeFormatName
			}

			 := protocol.FormatTime(, )
			if  != protocol.UnixTimeFormatName {
				 = `"` +  + `"`
			}

			.WriteString()
		case []byte:
			if !.IsNil() {
				.WriteByte('"')
for small buffers, using Encode directly is much faster.
					 := make([]byte, base64.StdEncoding.EncodedLen(len()))
					base64.StdEncoding.Encode(, )
					.Write()
for large buffers, avoid unnecessary extra temporary buffer space.
					 := base64.NewEncoder(base64.StdEncoding, )
					.Write()
					.Close()
				}
				.WriteByte('"')
			}
		case aws.JSONValue:
			,  := protocol.EncodeJSONValue(, protocol.QuotedEscape)
			if  != nil {
				return fmt.Errorf("unable to encode JSONValue, %v", )
			}
			.WriteString()
		default:
			return fmt.Errorf("unsupported JSON value %v (%s)", .Interface(), .Type())
		}
	}
	return nil
}

var hex = "0123456789abcdef"

func ( string,  *bytes.Buffer) {
	.WriteByte('"')
	for  := 0;  < len(); ++ {
		if [] == '"' {
			.WriteString(`\"`)
		} else if [] == '\\' {
			.WriteString(`\\`)
		} else if [] == '\b' {
			.WriteString(`\b`)
		} else if [] == '\f' {
			.WriteString(`\f`)
		} else if [] == '\r' {
			.WriteString(`\r`)
		} else if [] == '\t' {
			.WriteString(`\t`)
		} else if [] == '\n' {
			.WriteString(`\n`)
		} else if [] < 32 {
			.WriteString("\\u00")
			.WriteByte(hex[[]>>4])
			.WriteByte(hex[[]&0xF])
		} else {
			.WriteByte([])
		}
	}
	.WriteByte('"')
}
Returns the reflection element of a value, if it is a pointer.
func ( reflect.Value) reflect.Value {
	for .Kind() == reflect.Ptr {
		 = .Elem()
	}
	return