package gojay

// TODO @afiune for now we are using the standard json unmarshaling but in
// the future it would be great to implement one here inside this repo
import 

// DecodeInterface reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by i.
//
// i must be an interface poiter
func ( *Decoder) ( *interface{}) error {
	if .isPooled == 1 {
		panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
	}
	 := .decodeInterface()
	return 
}

func ( *Decoder) ( *interface{}) error {
	, ,  := .getObject()
	if  != nil {
		.cursor = 
		return 
	}

	// if start & end are equal the object is a null, don't unmarshal
	if  ==  {
		return nil
	}

	 := .data[:]
	if  = json.Unmarshal(, );  != nil {
		return 
	}

	.cursor = 
	return nil
}

// @afiune Maybe return the type as well?
func ( *Decoder) () ( int,  int,  error) {
	// start cursor
	for ; .cursor < .length || .read(); .cursor++ {
		switch .data[.cursor] {
		case ' ', '\n', '\t', '\r', ',':
			continue
		// is null
		case 'n':
			.cursor++
			 = .assertNull()
			if  != nil {
				return
			}
			// Set start & end to the same cursor to indicate the object
			// is a null and should not be unmarshal
			 = .cursor
			 = .cursor
			return
		case 't':
			 = .cursor
			.cursor++
			 = .assertTrue()
			if  != nil {
				return
			}
			 = .cursor
			.cursor++
			return
		// is false
		case 'f':
			 = .cursor
			.cursor++
			 = .assertFalse()
			if  != nil {
				return
			}
			 = .cursor
			.cursor++
			return
		// is an object
		case '{':
			 = .cursor
			.cursor++
			,  = .skipObject()
			.cursor = 
			return
		// is string
		case '"':
			 = .cursor
			.cursor++
			, ,  = .getString()
			--
			.cursor = 
			return
		// is array
		case '[':
			 = .cursor
			.cursor++
			,  = .skipArray()
			.cursor = 
			return
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
			 = .cursor
			,  = .skipNumber()
			.cursor = 
			return
		default:
			 = .raiseInvalidJSONErr(.cursor)
			return
		}
	}
	 = .raiseInvalidJSONErr(.cursor)
	return
}

// Add Values functions

// AddInterface decodes the JSON value within an object or an array to a interface{}.
func ( *Decoder) ( *interface{}) error {
	return .Interface()
}

// Interface decodes the JSON value within an object or an array to an interface{}.
func ( *Decoder) ( *interface{}) error {
	 := .decodeInterface()
	if  != nil {
		return 
	}
	.called |= 1
	return nil
}