package jsonutil

import (
	
	
	
	
	
	
	
	
	

	
	
	
)

var millisecondsFloat = new(big.Float).SetInt64(1e3)
UnmarshalJSONError unmarshal's the reader's JSON document into the passed in type. The value to unmarshal the json document into must be a pointer to the type.
func ( interface{},  io.Reader) error {
	var  bytes.Buffer
	 := io.TeeReader(, &)

	 := json.NewDecoder().Decode()
	if  != nil {
		 := "failed decoding error message"
		if  == io.EOF {
			 = "error message missing"
			 = nil
		}
		return awserr.NewUnmarshalError(, , .Bytes())
	}

	return nil
}
UnmarshalJSON reads a stream and unmarshals the results in object v.
func ( interface{},  io.Reader) error {
	var  interface{}

	 := json.NewDecoder()
	.UseNumber()
	 := .Decode(&)
	if  == io.EOF {
		return nil
	} else if  != nil {
		return 
	}

	return unmarshaler{}.unmarshalAny(reflect.ValueOf(), , "")
}
UnmarshalJSONCaseInsensitive reads a stream and unmarshals the result into the object v. Ignores casing for structure members.
func ( interface{},  io.Reader) error {
	var  interface{}

	 := json.NewDecoder()
	.UseNumber()
	 := .Decode(&)
	if  == io.EOF {
		return nil
	} else if  != nil {
		return 
	}

	return unmarshaler{
		caseInsensitive: true,
	}.unmarshalAny(reflect.ValueOf(), , "")
}

type unmarshaler struct {
	caseInsensitive bool
}

func ( unmarshaler) ( reflect.Value,  interface{},  reflect.StructTag) error {
	 := .Type()
	if .Kind() == reflect.Ptr {
		 = .Elem() // check kind of actual element type
	}

	 := .Get("type")
	if  == "" {
		switch .Kind() {
also it can't be a time object
			if ,  := .Interface().(*time.Time); ! {
				 = "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 .unmarshalStruct(, , )
	case "list":
		return .unmarshalList(, , )
	case "map":
		return .unmarshalMap(, , )
	default:
		return .unmarshalScalar(, , )
	}
}

func ( unmarshaler) ( reflect.Value,  interface{},  reflect.StructTag) error {
	if  == nil {
		return nil
	}
	,  := .(map[string]interface{})
	if ! {
		return fmt.Errorf("JSON value is not a structure (%#v)", )
	}

	 := .Type()
	if .Kind() == reflect.Ptr {
		if .IsNil() { // create the structure if it's nil
			 := reflect.New(.Type().Elem())
			.Set()
			 = 
		}

		 = .Elem()
		 = .Elem()
	}
unwrap any payloads
	if  := .Get("payload");  != "" {
		,  := .FieldByName()
		return .unmarshalAny(.FieldByName(), , .Tag)
	}

	for  := 0;  < .NumField(); ++ {
		 := .Field()
		if .PkgPath != "" {
			continue // ignore unexported fields
		}
figure out what this field is called
		 := .Name
		if  := .Tag.Get("locationName");  != "" {
			 = 
		}
		if .caseInsensitive {
Fallback to uncased name search if the exact name didn't match.
				for ,  := range  {
					if strings.EqualFold(, ) {
						[] = 
					}
				}
			}
		}

		 := .FieldByIndex(.Index)
		 := .unmarshalAny(, [], .Tag)
		if  != nil {
			return 
		}
	}
	return nil
}

func ( unmarshaler) ( reflect.Value,  interface{},  reflect.StructTag) error {
	if  == nil {
		return nil
	}
	,  := .([]interface{})
	if ! {
		return fmt.Errorf("JSON value is not a list (%#v)", )
	}

	if .IsNil() {
		 := len()
		.Set(reflect.MakeSlice(.Type(), , ))
	}

	for ,  := range  {
		 := .unmarshalAny(.Index(), , "")
		if  != nil {
			return 
		}
	}

	return nil
}

func ( unmarshaler) ( reflect.Value,  interface{},  reflect.StructTag) error {
	if  == nil {
		return nil
	}
	,  := .(map[string]interface{})
	if ! {
		return fmt.Errorf("JSON value is not a map (%#v)", )
	}

	if .IsNil() {
		.Set(reflect.MakeMap(.Type()))
	}

	for ,  := range  {
		 := reflect.ValueOf()
		 := reflect.New(.Type().Elem()).Elem()

		.unmarshalAny(, , "")
		.SetMapIndex(, )
	}

	return nil
}

func ( unmarshaler) ( reflect.Value,  interface{},  reflect.StructTag) error {

	switch d := .(type) {
	case nil:
		return nil // nothing to do here
	case string:
		switch .Interface().(type) {
		case *string:
			.Set(reflect.ValueOf(&))
		case []byte:
			,  := base64.StdEncoding.DecodeString()
			if  != nil {
				return 
			}
			.Set(reflect.ValueOf())
		case *time.Time:
			 := .Get("timestampFormat")
			if len() == 0 {
				 = protocol.ISO8601TimeFormatName
			}

			,  := protocol.ParseTime(, )
			if  != nil {
				return 
			}
			.Set(reflect.ValueOf(&))
No need to use escaping as the value is a non-quoted string.
			,  := protocol.DecodeJSONValue(, protocol.NoEscape)
			if  != nil {
				return 
			}
			.Set(reflect.ValueOf())
		default:
			return fmt.Errorf("unsupported value: %v (%s)", .Interface(), .Type())
		}
	case json.Number:
		switch .Interface().(type) {
Retain the old behavior where we would just truncate the float64 calling d.Int64() here could cause an invalid syntax error due to the usage of strconv.ParseInt
			,  := .Float64()
			if  != nil {
				return 
			}
			 := int64()
			.Set(reflect.ValueOf(&))
		case *float64:
			,  := .Float64()
			if  != nil {
				return 
			}
			.Set(reflect.ValueOf(&))
		case *time.Time:
			,  := new(big.Float).SetString(.String())
			if ! {
				return fmt.Errorf("unsupported float time representation: %v", .String())
			}
			 = .Mul(, millisecondsFloat)
			,  := .Int64()
			 := time.Unix(0, *1e6).UTC()
			.Set(reflect.ValueOf(&))
		default:
			return fmt.Errorf("unsupported value: %v (%s)", .Interface(), .Type())
		}
	case bool:
		switch .Interface().(type) {
		case *bool:
			.Set(reflect.ValueOf(&))
		default:
			return fmt.Errorf("unsupported value: %v (%s)", .Interface(), .Type())
		}
	default:
		return fmt.Errorf("unsupported JSON value (%v)", )
	}
	return nil