package jsoniter

import (
	
	
	
	
	
	
)

var floatDigits []int8

const invalidCharForNumber = int8(-1)
const endOfNumber = int8(-2)
const dotInNumber = int8(-3)

func init() {
	floatDigits = make([]int8, 256)
	for  := 0;  < len(floatDigits); ++ {
		floatDigits[] = invalidCharForNumber
	}
	for  := int8('0');  <= int8('9'); ++ {
		floatDigits[] =  - int8('0')
	}
	floatDigits[','] = endOfNumber
	floatDigits[']'] = endOfNumber
	floatDigits['}'] = endOfNumber
	floatDigits[' '] = endOfNumber
	floatDigits['\t'] = endOfNumber
	floatDigits['\n'] = endOfNumber
	floatDigits['.'] = dotInNumber
}

// ReadBigFloat read big.Float
func ( *Iterator) () ( *big.Float) {
	 := .readNumberAsString()
	if .Error != nil && .Error != io.EOF {
		return nil
	}
	 := 64
	if len() >  {
		 = len()
	}
	, ,  := big.ParseFloat(, 10, uint(), big.ToZero)
	if  != nil {
		.Error = 
		return nil
	}
	return 
}

// ReadBigInt read big.Int
func ( *Iterator) () ( *big.Int) {
	 := .readNumberAsString()
	if .Error != nil && .Error != io.EOF {
		return nil
	}
	 = big.NewInt(0)
	var  bool
	,  = .SetString(, 10)
	if ! {
		.ReportError("ReadBigInt", "invalid big int")
		return nil
	}
	return 
}

//ReadFloat32 read float32
func ( *Iterator) () ( float32) {
	 := .nextToken()
	if  == '-' {
		return -.readPositiveFloat32()
	}
	.unreadByte()
	return .readPositiveFloat32()
}

func ( *Iterator) () ( float32) {
	 := .head
	// first char
	if  == .tail {
		return .readFloat32SlowPath()
	}
	 := .buf[]
	++
	 := floatDigits[]
	switch  {
	case invalidCharForNumber:
		return .readFloat32SlowPath()
	case endOfNumber:
		.ReportError("readFloat32", "empty number")
		return
	case dotInNumber:
		.ReportError("readFloat32", "leading dot is invalid")
		return
	case 0:
		if  == .tail {
			return .readFloat32SlowPath()
		}
		 = .buf[]
		switch  {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			.ReportError("readFloat32", "leading zero is invalid")
			return
		}
	}
	 := uint64()
	// chars before dot
:
	for ;  < .tail; ++ {
		 = .buf[]
		 := floatDigits[]
		switch  {
		case invalidCharForNumber:
			return .readFloat32SlowPath()
		case endOfNumber:
			.head = 
			return float32()
		case dotInNumber:
			break 
		}
		if  > uint64SafeToMultiple10 {
			return .readFloat32SlowPath()
		}
		 = ( << 3) + ( << 1) + uint64() // value = value * 10 + ind;
	}
	// chars after dot
	if  == '.' {
		++
		 := 0
		if  == .tail {
			return .readFloat32SlowPath()
		}
		for ;  < .tail; ++ {
			 = .buf[]
			 := floatDigits[]
			switch  {
			case endOfNumber:
				if  > 0 &&  < len(pow10) {
					.head = 
					return float32(float64() / float64(pow10[]))
				}
				// too many decimal places
				return .readFloat32SlowPath()
			case invalidCharForNumber, dotInNumber:
				return .readFloat32SlowPath()
			}
			++
			if  > uint64SafeToMultiple10 {
				return .readFloat32SlowPath()
			}
			 = ( << 3) + ( << 1) + uint64()
		}
	}
	return .readFloat32SlowPath()
}

func ( *Iterator) () ( string) {
	 := [16]byte{}
	 := [0:0]
:
	for {
		for  := .head;  < .tail; ++ {
			 := .buf[]
			switch  {
			case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
				 = append(, )
				continue
			default:
				.head = 
				break 
			}
		}
		if !.loadMore() {
			break
		}
	}
	if .Error != nil && .Error != io.EOF {
		return
	}
	if len() == 0 {
		.ReportError("readNumberAsString", "invalid number")
	}
	return *(*string)(unsafe.Pointer(&))
}

func ( *Iterator) () ( float32) {
	 := .readNumberAsString()
	if .Error != nil && .Error != io.EOF {
		return
	}
	 := validateFloat()
	if  != "" {
		.ReportError("readFloat32SlowPath", )
		return
	}
	,  := strconv.ParseFloat(, 32)
	if  != nil {
		.Error = 
		return
	}
	return float32()
}

// ReadFloat64 read float64
func ( *Iterator) () ( float64) {
	 := .nextToken()
	if  == '-' {
		return -.readPositiveFloat64()
	}
	.unreadByte()
	return .readPositiveFloat64()
}

func ( *Iterator) () ( float64) {
	 := .head
	// first char
	if  == .tail {
		return .readFloat64SlowPath()
	}
	 := .buf[]
	++
	 := floatDigits[]
	switch  {
	case invalidCharForNumber:
		return .readFloat64SlowPath()
	case endOfNumber:
		.ReportError("readFloat64", "empty number")
		return
	case dotInNumber:
		.ReportError("readFloat64", "leading dot is invalid")
		return
	case 0:
		if  == .tail {
			return .readFloat64SlowPath()
		}
		 = .buf[]
		switch  {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			.ReportError("readFloat64", "leading zero is invalid")
			return
		}
	}
	 := uint64()
	// chars before dot
:
	for ;  < .tail; ++ {
		 = .buf[]
		 := floatDigits[]
		switch  {
		case invalidCharForNumber:
			return .readFloat64SlowPath()
		case endOfNumber:
			.head = 
			return float64()
		case dotInNumber:
			break 
		}
		if  > uint64SafeToMultiple10 {
			return .readFloat64SlowPath()
		}
		 = ( << 3) + ( << 1) + uint64() // value = value * 10 + ind;
	}
	// chars after dot
	if  == '.' {
		++
		 := 0
		if  == .tail {
			return .readFloat64SlowPath()
		}
		for ;  < .tail; ++ {
			 = .buf[]
			 := floatDigits[]
			switch  {
			case endOfNumber:
				if  > 0 &&  < len(pow10) {
					.head = 
					return float64() / float64(pow10[])
				}
				// too many decimal places
				return .readFloat64SlowPath()
			case invalidCharForNumber, dotInNumber:
				return .readFloat64SlowPath()
			}
			++
			if  > uint64SafeToMultiple10 {
				return .readFloat64SlowPath()
			}
			 = ( << 3) + ( << 1) + uint64()
			if  > maxFloat64 {
				return .readFloat64SlowPath()
			}
		}
	}
	return .readFloat64SlowPath()
}

func ( *Iterator) () ( float64) {
	 := .readNumberAsString()
	if .Error != nil && .Error != io.EOF {
		return
	}
	 := validateFloat()
	if  != "" {
		.ReportError("readFloat64SlowPath", )
		return
	}
	,  := strconv.ParseFloat(, 64)
	if  != nil {
		.Error = 
		return
	}
	return 
}

func validateFloat( string) string {
	// strconv.ParseFloat is not validating `1.` or `1.e1`
	if len() == 0 {
		return "empty number"
	}
	if [0] == '-' {
		return "-- is not valid"
	}
	 := strings.IndexByte(, '.')
	if  != -1 {
		if  == len()-1 {
			return "dot can not be last character"
		}
		switch [+1] {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		default:
			return "missing digit after dot"
		}
	}
	return ""
}

// ReadNumber read json.Number
func ( *Iterator) () ( json.Number) {
	return json.Number(.readNumberAsString())
}