package decoder

import (
	
	
	
	
	

	
)

const (
	initBufSize = 512
)

type Stream struct {
	buf                   []byte
	bufSize               int64
	length                int64
	r                     io.Reader
	offset                int64
	cursor                int64
	filledBuffer          bool
	allRead               bool
	UseNumber             bool
	DisallowUnknownFields bool
	Option                *Option
}

func ( io.Reader) *Stream {
	return &Stream{
		r:       ,
		bufSize: initBufSize,
		buf:     make([]byte, initBufSize),
		Option:  &Option{},
	}
}

func ( *Stream) () int64 {
	return .totalOffset()
}

func ( *Stream) () io.Reader {
	 := int64(len(.buf))
	for  := .cursor;  < ; ++ {
		if .buf[] == nul {
			return bytes.NewReader(.buf[.cursor:])
		}
	}
	return bytes.NewReader(.buf[.cursor:])
}

func ( *Stream) () error {
	for {
		switch .char() {
		case ' ', '\t', '\r', '\n':
			.cursor++
			continue
		case ',', ':':
			.cursor++
			return nil
		case nul:
			if .read() {
				continue
			}
			return io.EOF
		}
		break
	}
	return nil
}

func ( *Stream) () int64 {
	return .offset + .cursor
}

func ( *Stream) () byte {
	return .buf[.cursor]
}

func ( *Stream) ( byte) bool {
	 := .buf[.cursor]
	if  == nul {
		.read()
		 = .buf[.cursor]
	}
	return  == 
}

func ( *Stream) () ([]byte, int64, unsafe.Pointer) {
	return .buf, .cursor, (*sliceHeader)(unsafe.Pointer(&.buf)).data
}

func ( *Stream) () unsafe.Pointer {
	return (*sliceHeader)(unsafe.Pointer(&.buf)).data
}

func ( *Stream) () ([]byte, int64, unsafe.Pointer) {
	.cursor-- // for retry ( because caller progress cursor position in each loop )
	return .buf, .cursor, (*sliceHeader)(unsafe.Pointer(&.buf)).data
}

func ( *Stream) () {
	.reset()
	.bufSize = int64(len(.buf))
}

func ( *Stream) () bool {
	for {
		switch .char() {
		case ' ', '\n', '\r', '\t':
			.cursor++
			continue
		case '}', ']':
			return false
		case nul:
			if .read() {
				continue
			}
			return false
		}
		break
	}
	return true
}

func ( *Stream) () (interface{}, error) {
	for {
		 := .char()
		switch  {
		case ' ', '\n', '\r', '\t':
			.cursor++
		case '{', '[', ']', '}':
			.cursor++
			return json.Delim(), nil
		case ',', ':':
			.cursor++
		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			 := floatBytes()
			 := *(*string)(unsafe.Pointer(&))
			if .UseNumber {
				return json.Number(), nil
			}
			,  := strconv.ParseFloat(, 64)
			if  != nil {
				return nil, 
			}
			return , nil
		case '"':
			,  := stringBytes()
			if  != nil {
				return nil, 
			}
			return string(), nil
		case 't':
			if  := trueBytes();  != nil {
				return nil, 
			}
			return true, nil
		case 'f':
			if  := falseBytes();  != nil {
				return nil, 
			}
			return false, nil
		case 'n':
			if  := nullBytes();  != nil {
				return nil, 
			}
			return nil, nil
		case nul:
			if .read() {
				continue
			}
			goto 
		default:
			return nil, errors.ErrInvalidCharacter(.char(), "token", .totalOffset())
		}
	}
:
	return nil, io.EOF
}

func ( *Stream) () {
	.offset += .cursor
	.buf = .buf[.cursor:]
	.length -= .cursor
	.cursor = 0
}

func ( *Stream) () []byte {
	if .filledBuffer {
		.bufSize *= 2
		 := .buf
		.buf = make([]byte, .bufSize)
		copy(.buf, )
	}
	 := .length - .cursor
	 := int64(0)
	for  := int64(0);  < ; ++ {
		if .buf[.cursor+] == nul {
			break
		}
		++
	}
	.length = .cursor + 
	return .buf[.cursor+:]
}

func ( *Stream) () bool {
	if .allRead {
		return false
	}
	 := .readBuf()
	 := len() - 1
	[] = nul
	,  := .r.Read([:])
	.length += int64()
	if  ==  {
		.filledBuffer = true
	} else {
		.filledBuffer = false
	}
	if  == io.EOF {
		.allRead = true
	} else if  != nil {
		return false
	}
	return true
}

func ( *Stream) () byte {
	 := .bufptr()
:
	 := char(, .cursor)
	switch  {
	case ' ', '\n', '\t', '\r':
		.cursor++
		goto 
	case nul:
		if .read() {
			 = .bufptr()
			goto 
		}
	}
	return 
}

func ( *Stream) ( int64) error {
	 := 1
	, ,  := .stat()
	for {
		switch char(, ) {
		case '{':
			++
			++
			if  > maxDecodeNestingDepth {
				return errors.ErrExceededMaxDepth(.char(), .cursor)
			}
		case '}':
			--
			--
			if  == 0 {
				.cursor =  + 1
				return nil
			}
		case '[':
			++
			if  > maxDecodeNestingDepth {
				return errors.ErrExceededMaxDepth(.char(), .cursor)
			}
		case ']':
			--
		case '"':
			for {
				++
				switch char(, ) {
				case '\\':
					++
					if char(, ) == nul {
						.cursor = 
						if .read() {
							_, ,  = .stat()
							continue
						}
						return errors.ErrUnexpectedEndOfJSON("string of object", )
					}
				case '"':
					goto 
				case nul:
					.cursor = 
					if .read() {
						_, ,  = .statForRetry()
						continue
					}
					return errors.ErrUnexpectedEndOfJSON("string of object", )
				}
			}
		case nul:
			.cursor = 
			if .read() {
				_, ,  = .stat()
				continue
			}
			return errors.ErrUnexpectedEndOfJSON("object of object", )
		}
	:
		++
	}
}

func ( *Stream) ( int64) error {
	 := 1
	, ,  := .stat()
	for {
		switch char(, ) {
		case '[':
			++
			++
			if  > maxDecodeNestingDepth {
				return errors.ErrExceededMaxDepth(.char(), .cursor)
			}
		case ']':
			--
			--
			if  == 0 {
				.cursor =  + 1
				return nil
			}
		case '{':
			++
			if  > maxDecodeNestingDepth {
				return errors.ErrExceededMaxDepth(.char(), .cursor)
			}
		case '}':
			--
		case '"':
			for {
				++
				switch char(, ) {
				case '\\':
					++
					if char(, ) == nul {
						.cursor = 
						if .read() {
							_, ,  = .stat()
							continue
						}
						return errors.ErrUnexpectedEndOfJSON("string of object", )
					}
				case '"':
					goto 
				case nul:
					.cursor = 
					if .read() {
						_, ,  = .statForRetry()
						continue
					}
					return errors.ErrUnexpectedEndOfJSON("string of object", )
				}
			}
		case nul:
			.cursor = 
			if .read() {
				_, ,  = .stat()
				continue
			}
			return errors.ErrUnexpectedEndOfJSON("array of object", )
		}
	:
		++
	}
}

func ( *Stream) ( int64) error {
	, ,  := .stat()
	for {
		switch char(, ) {
		case ' ', '\n', '\t', '\r':
			++
			continue
		case nul:
			.cursor = 
			if .read() {
				_, ,  = .stat()
				continue
			}
			return errors.ErrUnexpectedEndOfJSON("value of object", .totalOffset())
		case '{':
			.cursor =  + 1
			return .skipObject( + 1)
		case '[':
			.cursor =  + 1
			return .skipArray( + 1)
		case '"':
			for {
				++
				switch char(, ) {
				case '\\':
					++
					if char(, ) == nul {
						.cursor = 
						if .read() {
							_, ,  = .stat()
							continue
						}
						return errors.ErrUnexpectedEndOfJSON("value of string", .totalOffset())
					}
				case '"':
					.cursor =  + 1
					return nil
				case nul:
					.cursor = 
					if .read() {
						_, ,  = .statForRetry()
						continue
					}
					return errors.ErrUnexpectedEndOfJSON("value of string", .totalOffset())
				}
			}
		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			for {
				++
				 := char(, )
				if floatTable[] {
					continue
				} else if  == nul {
					if .read() {
						_, ,  = .stat()
						continue
					}
				}
				.cursor = 
				return nil
			}
		case 't':
			.cursor = 
			if  := trueBytes();  != nil {
				return 
			}
			return nil
		case 'f':
			.cursor = 
			if  := falseBytes();  != nil {
				return 
			}
			return nil
		case 'n':
			.cursor = 
			if  := nullBytes();  != nil {
				return 
			}
			return nil
		}
		++
	}
}

func nullBytes( *Stream) error {
	// current cursor's character is 'n'
	.cursor++
	if .char() != 'u' {
		if  := retryReadNull();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 'l' {
		if  := retryReadNull();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 'l' {
		if  := retryReadNull();  != nil {
			return 
		}
	}
	.cursor++
	return nil
}

func retryReadNull( *Stream) error {
	if .char() == nul && .read() {
		return nil
	}
	return errors.ErrInvalidCharacter(.char(), "null", .totalOffset())
}

func trueBytes( *Stream) error {
	// current cursor's character is 't'
	.cursor++
	if .char() != 'r' {
		if  := retryReadTrue();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 'u' {
		if  := retryReadTrue();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 'e' {
		if  := retryReadTrue();  != nil {
			return 
		}
	}
	.cursor++
	return nil
}

func retryReadTrue( *Stream) error {
	if .char() == nul && .read() {
		return nil
	}
	return errors.ErrInvalidCharacter(.char(), "bool(true)", .totalOffset())
}

func falseBytes( *Stream) error {
	// current cursor's character is 'f'
	.cursor++
	if .char() != 'a' {
		if  := retryReadFalse();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 'l' {
		if  := retryReadFalse();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 's' {
		if  := retryReadFalse();  != nil {
			return 
		}
	}
	.cursor++
	if .char() != 'e' {
		if  := retryReadFalse();  != nil {
			return 
		}
	}
	.cursor++
	return nil
}

func retryReadFalse( *Stream) error {
	if .char() == nul && .read() {
		return nil
	}
	return errors.ErrInvalidCharacter(.char(), "bool(false)", .totalOffset())
}