You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	merge lexer with iterator
This commit is contained in:
		
							
								
								
									
										606
									
								
								jsoniter.go
									
									
									
									
									
								
							
							
						
						
									
										606
									
								
								jsoniter.go
									
									
									
									
									
								
							| @@ -1,358 +1,294 @@ | |||||||
| package jsoniter | package jsoniter | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	fflib "github.com/pquerna/ffjson/fflib/v1" | 	"io" | ||||||
| 	"strconv" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"unicode/utf16" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Token fflib.FFTok |  | ||||||
|  |  | ||||||
| const TokenInteger = Token(fflib.FFTok_integer) |  | ||||||
| const TokenDouble = Token(fflib.FFTok_double) |  | ||||||
| const TokenBool = Token(fflib.FFTok_bool) |  | ||||||
| const TokenError = Token(fflib.FFTok_error) |  | ||||||
| const TokenLeftBrace = Token(fflib.FFTok_left_brace) |  | ||||||
| const TokenLeftBracket = Token(fflib.FFTok_left_bracket) |  | ||||||
| const TokenRightBrace = Token(fflib.FFTok_right_brace) |  | ||||||
| const TokenRightBracket = Token(fflib.FFTok_right_bracket) |  | ||||||
| const TokenComma = Token(fflib.FFTok_comma) |  | ||||||
| const TokenString = Token(fflib.FFTok_string) |  | ||||||
| const TokenColon = Token(fflib.FFTok_colon) |  | ||||||
|  |  | ||||||
| func (tok Token) ToString() string { |  | ||||||
| 	return fmt.Sprintf("%v", fflib.FFTok(tok)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type Iterator struct { | type Iterator struct { | ||||||
| 	ErrorHandler func(error) | 	reader io.Reader | ||||||
| 	lexer        *fflib.FFLexer | 	buf    []byte | ||||||
|  | 	head   int | ||||||
|  | 	tail   int | ||||||
|  | 	Error  error | ||||||
| } | } | ||||||
|  |  | ||||||
| type UnexpectedToken struct { | func Parse(reader io.Reader, bufSize int) *Iterator { | ||||||
| 	Expected Token | 	return &Iterator{ | ||||||
| 	Actual   Token | 		reader: reader, | ||||||
| } | 		buf: make([]byte, bufSize), | ||||||
|  | 		head: 0, | ||||||
| func (err *UnexpectedToken) Error() string { | 		tail: 0, | ||||||
| 	return fmt.Sprintf("unexpected token, expected %v, actual %v", fflib.FFTok(err.Expected), fflib.FFTok(err.Actual)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewIterator(input []byte) Iterator { |  | ||||||
| 	lexer := fflib.NewFFLexer(input) |  | ||||||
| 	return Iterator{ |  | ||||||
| 		lexer: lexer, |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (iter Iterator) ReadArray(callback func(Iterator, int)) { | func ParseBytes(input []byte) *Iterator { | ||||||
| 	lexer := iter.lexer | 	return &Iterator{ | ||||||
| 	if !iter.AssertToken(TokenLeftBrace) { | 		reader: nil, | ||||||
| 		return | 		buf: input, | ||||||
|  | 		head: 0, | ||||||
|  | 		tail: len(input), | ||||||
| 	} | 	} | ||||||
| 	index := 0 | } | ||||||
| 	for { |  | ||||||
| 		lexer.Scan() | func ParseString(input string) *Iterator { | ||||||
| 		callback(iter, index) | 	return ParseBytes([]byte(input)) | ||||||
| 		index += 1 | } | ||||||
| 		if iter.Token() != TokenComma { |  | ||||||
| 			break | func (iter *Iterator) ReportError(operation string, msg string) { | ||||||
|  | 	iter.Error = fmt.Errorf("%s: %s, parsing %v at %s", operation, msg, iter.head, string(iter.buf[0:iter.tail])) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (iter *Iterator) readByte() (ret byte) { | ||||||
|  | 	if iter.head == iter.tail { | ||||||
|  | 		if iter.reader == nil { | ||||||
|  | 			iter.Error = io.EOF | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
| 	} | 		n, err := iter.reader.Read(iter.buf) | ||||||
| 	iter.AssertToken(TokenRightBrace) | 		if err != nil { | ||||||
| 	lexer.Scan() | 			iter.Error = err | ||||||
| } | 			return | ||||||
|  |  | ||||||
| func (iter Iterator) ReadObject(callback func(Iterator, string)) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenLeftBracket) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	for { |  | ||||||
| 		lexer.Scan() |  | ||||||
| 		field := iter.ReadString() |  | ||||||
| 		iter.AssertToken(TokenColon) |  | ||||||
| 		lexer.Scan() |  | ||||||
| 		callback(iter, field) |  | ||||||
| 		if iter.Token() != TokenComma { |  | ||||||
| 			break |  | ||||||
| 		} | 		} | ||||||
| 	} | 		if n == 0 { | ||||||
| 	iter.AssertToken(TokenRightBracket) | 			iter.Error = io.EOF | ||||||
| 	lexer.Scan() | 			return | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) Skip() { |  | ||||||
| 	switch iter.Token() { |  | ||||||
| 	case TokenLeftBracket: |  | ||||||
| 		iter.ReadObject(func(iter Iterator, field string) { |  | ||||||
| 			iter.Skip() |  | ||||||
| 		}) |  | ||||||
| 	case TokenLeftBrace: |  | ||||||
| 		iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| 			iter.Skip() |  | ||||||
| 		}) |  | ||||||
| 	default: |  | ||||||
| 		iter.lexer.Scan() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadInt8() (rval int8) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseInt(string(field), 10, 8) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return int8(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadInt16() (rval int16) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseInt(string(field), 10, 16) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return int16(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadInt32() (rval int32) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseInt(string(field), 10, 32) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return int32(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadInt64() (rval int64) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseInt(string(field), 10, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return number |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadInt() (rval int) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	n, err := lexer.LexInt64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return int(n) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadUint() (rval uint) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseUint(string(field), 10, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return uint(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadUint8() (rval uint8) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseUint(string(field), 10, 8) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return uint8(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadUint16() (rval uint16) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseUint(string(field), 10, 16) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return uint16(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadUint32() (rval uint32) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseUint(string(field), 10, 32) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return uint32(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadUint64() (rval uint64) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenInteger) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseUint(string(field), 10, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return uint64(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadFloat32() (rval float32) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenDouble) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseFloat(string(field), 32) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return float32(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadFloat64() (rval float64) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenDouble) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	number, err := strconv.ParseFloat(string(field), 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(fmt.Errorf("failed to convert %v: %v", string(field), err.Error())) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return float64(number) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) ReadString() (rval string) { |  | ||||||
| 	lexer := iter.lexer |  | ||||||
| 	if !iter.AssertToken(TokenString) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	field, err := lexer.CaptureField(lexer.Token) |  | ||||||
| 	if err != nil { |  | ||||||
| 		iter.OnError(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	lexer.Scan() |  | ||||||
| 	return string(field[1:len(field) - 1]) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (iter Iterator) AssertToken(expected Token) bool { |  | ||||||
| 	actual := iter.Token() |  | ||||||
| 	if expected != actual { |  | ||||||
| 		if actual == TokenError { |  | ||||||
| 			fmt.Println(iter.lexer.BigError.Error()) |  | ||||||
| 		} | 		} | ||||||
| 		iter.OnError(&UnexpectedToken{ | 		iter.head = 0 | ||||||
| 			Expected: expected, | 		iter.tail = n | ||||||
| 			Actual: actual, |  | ||||||
| 		}) |  | ||||||
| 		return false |  | ||||||
| 	} | 	} | ||||||
| 	return true | 	ret = iter.buf[iter.head] | ||||||
|  | 	iter.head += 1 | ||||||
|  | 	return ret | ||||||
| } | } | ||||||
|  |  | ||||||
| func (iter Iterator) Token() Token { | func (iter *Iterator) unreadByte() { | ||||||
| 	return Token(iter.lexer.Token) | 	if iter.head == 0 { | ||||||
|  | 		iter.ReportError("unreadByte", "unread too many bytes") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	iter.head -= 1 | ||||||
|  | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| func (iter *Iterator) OnError(err error) { | const maxUint64 = (1 << 64 - 1) | ||||||
| 	if iter.ErrorHandler == nil { | const cutoffUint64 = maxUint64 / 10 + 1 | ||||||
| 		panic(err.Error()) | const maxUint32 = (1 << 32 - 1) | ||||||
|  | const cutoffUint32 = maxUint32 / 10 + 1 | ||||||
|  |  | ||||||
|  | func (iter *Iterator) ReadUint64() (ret uint64) { | ||||||
|  | 	c := iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* a single zero, or a series of integers */ | ||||||
|  | 	if c == '0' { | ||||||
|  | 		return 0 | ||||||
|  | 	} else if c >= '1' && c <= '9' { | ||||||
|  | 		for c >= '0' && c <= '9' { | ||||||
|  | 			var v byte | ||||||
|  | 			v = c - '0' | ||||||
|  | 			if ret >= cutoffUint64 { | ||||||
|  | 				iter.ReportError("ReadUint64", "overflow") | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			ret = ret * uint64(10) + uint64(v) | ||||||
|  | 			c = iter.readByte() | ||||||
|  | 			if iter.Error != nil { | ||||||
|  | 				if iter.Error == io.EOF { | ||||||
|  | 					break | ||||||
|  | 				} else { | ||||||
|  | 					return 0 | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if iter.Error != io.EOF { | ||||||
|  | 			iter.unreadByte() | ||||||
|  | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		iter.ErrorHandler(err) | 		iter.ReportError("ReadUint64", "expects 0~9") | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| } | 	return ret | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (iter *Iterator) ReadInt64() (ret int64) { | ||||||
|  | 	c := iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* optional leading minus */ | ||||||
|  | 	if c == '-' { | ||||||
|  | 		n := iter.ReadUint64() | ||||||
|  | 		return -int64(n) | ||||||
|  | 	} else { | ||||||
|  | 		iter.unreadByte() | ||||||
|  | 		n := iter.ReadUint64() | ||||||
|  | 		return int64(n) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (iter *Iterator) ReadString() (ret string) { | ||||||
|  | 	str := make([]byte, 0, 10) | ||||||
|  | 	c := iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if c != '"' { | ||||||
|  | 		iter.ReportError("ReadString", "expects quote") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	for { | ||||||
|  | 		c = iter.readByte() | ||||||
|  | 		if iter.Error != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		switch c { | ||||||
|  | 		case '\\': | ||||||
|  | 			c = iter.readByte() | ||||||
|  | 			if iter.Error != nil { | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			switch c { | ||||||
|  | 			case 'u': | ||||||
|  | 				r := iter.readU4() | ||||||
|  | 				if iter.Error != nil { | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 				if utf16.IsSurrogate(r) { | ||||||
|  | 					c = iter.readByte() | ||||||
|  | 					if iter.Error != nil { | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
|  | 					if c != '\\' { | ||||||
|  | 						iter.ReportError("ReadString", | ||||||
|  | 							`expects \u after utf16 surrogate, but \ not found`) | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
|  | 					c = iter.readByte() | ||||||
|  | 					if iter.Error != nil { | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
|  | 					if c != 'u' { | ||||||
|  | 						iter.ReportError("ReadString", | ||||||
|  | 							`expects \u after utf16 surrogate, but \u not found`) | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
|  | 					r2 := iter.readU4() | ||||||
|  | 					if iter.Error != nil { | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
|  | 					combined := utf16.DecodeRune(r, r2) | ||||||
|  | 					str = appendRune(str, combined) | ||||||
|  | 				} else { | ||||||
|  | 					str = appendRune(str, r) | ||||||
|  | 				} | ||||||
|  | 			case '"': | ||||||
|  | 				str = append(str, '"') | ||||||
|  | 			case '\\': | ||||||
|  | 				str = append(str, '\\') | ||||||
|  | 			case '/': | ||||||
|  | 				str = append(str, '/') | ||||||
|  | 			case 'b': | ||||||
|  | 				str = append(str, '\b') | ||||||
|  | 			case 'f': | ||||||
|  | 				str = append(str, '\f') | ||||||
|  | 			case 'n': | ||||||
|  | 				str = append(str, '\n') | ||||||
|  | 			case 'r': | ||||||
|  | 				str = append(str, '\r') | ||||||
|  | 			case 't': | ||||||
|  | 				str = append(str, '\t') | ||||||
|  | 			default: | ||||||
|  | 				iter.ReportError("ReadString", | ||||||
|  | 					`invalid escape char after \`) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		case '"': | ||||||
|  | 			return string(str) | ||||||
|  | 		default: | ||||||
|  | 			str = append(str, c) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (iter *Iterator) readU4() (ret rune) { | ||||||
|  | 	for i := 0; i < 4; i++ { | ||||||
|  | 		c := iter.readByte() | ||||||
|  | 		if iter.Error != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		if (c >= '0' && c <= '9') { | ||||||
|  | 			if ret >= cutoffUint32 { | ||||||
|  | 				iter.ReportError("readU4", "overflow") | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			ret = ret * 16 + rune(c - '0') | ||||||
|  | 		} else if ((c >= 'a' && c <= 'f') ) { | ||||||
|  | 			if ret >= cutoffUint32 { | ||||||
|  | 				iter.ReportError("readU4", "overflow") | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			ret = ret * 16 + rune(c - 'a' + 10) | ||||||
|  | 		} else { | ||||||
|  | 			iter.ReportError("readU4", "expects 0~9 or a~f") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	t1 = 0x00 // 0000 0000 | ||||||
|  | 	tx = 0x80 // 1000 0000 | ||||||
|  | 	t2 = 0xC0 // 1100 0000 | ||||||
|  | 	t3 = 0xE0 // 1110 0000 | ||||||
|  | 	t4 = 0xF0 // 1111 0000 | ||||||
|  | 	t5 = 0xF8 // 1111 1000 | ||||||
|  |  | ||||||
|  | 	maskx = 0x3F // 0011 1111 | ||||||
|  | 	mask2 = 0x1F // 0001 1111 | ||||||
|  | 	mask3 = 0x0F // 0000 1111 | ||||||
|  | 	mask4 = 0x07 // 0000 0111 | ||||||
|  |  | ||||||
|  | 	rune1Max = 1 << 7 - 1 | ||||||
|  | 	rune2Max = 1 << 11 - 1 | ||||||
|  | 	rune3Max = 1 << 16 - 1 | ||||||
|  |  | ||||||
|  | 	surrogateMin = 0xD800 | ||||||
|  | 	surrogateMax = 0xDFFF | ||||||
|  |  | ||||||
|  | 	MaxRune = '\U0010FFFF' // Maximum valid Unicode code point. | ||||||
|  | 	RuneError = '\uFFFD'     // the "error" Rune or "Unicode replacement character" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func appendRune(p []byte, r rune) []byte { | ||||||
|  | 	// Negative values are erroneous. Making it unsigned addresses the problem. | ||||||
|  | 	switch i := uint32(r); { | ||||||
|  | 	case i <= rune1Max: | ||||||
|  | 		p = append(p, byte(r)) | ||||||
|  | 		return p | ||||||
|  | 	case i <= rune2Max: | ||||||
|  | 		p = append(p, t2 | byte(r >> 6)) | ||||||
|  | 		p = append(p, tx | byte(r) & maskx) | ||||||
|  | 		return p | ||||||
|  | 	case i > MaxRune, surrogateMin <= i && i <= surrogateMax: | ||||||
|  | 		r = RuneError | ||||||
|  | 		fallthrough | ||||||
|  | 	case i <= rune3Max: | ||||||
|  | 		p = append(p, t3 | byte(r >> 12)) | ||||||
|  | 		p = append(p, tx | byte(r >> 6) & maskx) | ||||||
|  | 		p = append(p, tx | byte(r) & maskx) | ||||||
|  | 		return p | ||||||
|  | 	default: | ||||||
|  | 		p = append(p, t4 | byte(r >> 18)) | ||||||
|  | 		p = append(p, tx | byte(r >> 12) & maskx) | ||||||
|  | 		p = append(p, tx | byte(r >> 6) & maskx) | ||||||
|  | 		p = append(p, tx | byte(r) & maskx) | ||||||
|  | 		return p | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										83
									
								
								jsoniter_int_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								jsoniter_int_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | package jsoniter | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 	"bytes" | ||||||
|  | 	"encoding/json" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func Test_uint64_0(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("0"), 4096) | ||||||
|  | 	val := iter.ReadUint64() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if val != 0 { | ||||||
|  | 		t.Fatal(val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_uint64_1(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("1"), 4096) | ||||||
|  | 	val := iter.ReadUint64() | ||||||
|  | 	if val != 1 { | ||||||
|  | 		t.Fatal(val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_uint64_100(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("100"), 4096) | ||||||
|  | 	val := iter.ReadUint64() | ||||||
|  | 	if val != 100 { | ||||||
|  | 		t.Fatal(val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_uint64_100_comma(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("100,"), 4096) | ||||||
|  | 	val := iter.ReadUint64() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if val != 100 { | ||||||
|  | 		t.Fatal(val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_uint64_invalid(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString(","), 4096) | ||||||
|  | 	iter.ReadUint64() | ||||||
|  | 	if iter.Error == nil { | ||||||
|  | 		t.FailNow() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_int64_100(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("100"), 4096) | ||||||
|  | 	val := iter.ReadInt64() | ||||||
|  | 	if val != 100 { | ||||||
|  | 		t.Fatal(val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_int64_minus_100(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("-100"), 4096) | ||||||
|  | 	val := iter.ReadInt64() | ||||||
|  | 	if val != -100 { | ||||||
|  | 		t.Fatal(val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Benchmark_jsoniter_int(b *testing.B) { | ||||||
|  | 	for n := 0; n < b.N; n++ { | ||||||
|  | 		iter := ParseString(`-100`) | ||||||
|  | 		iter.ReadInt64() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Benchmark_json_int(b *testing.B) { | ||||||
|  | 	for n := 0; n < b.N; n++ { | ||||||
|  | 		result := int64(0) | ||||||
|  | 		json.Unmarshal([]byte(`-100`), &result) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										84
									
								
								jsoniter_io_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								jsoniter_io_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | package jsoniter | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 	"bytes" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func Test_read_by_one(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("abc"), 1) | ||||||
|  | 	b := iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if b != 'a' { | ||||||
|  | 		t.Fatal(b) | ||||||
|  | 	} | ||||||
|  | 	iter.unreadByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	iter.unreadByte() | ||||||
|  | 	if iter.Error == nil { | ||||||
|  | 		t.FailNow() | ||||||
|  | 	} | ||||||
|  | 	iter.Error = nil | ||||||
|  | 	b = iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if b != 'a' { | ||||||
|  | 		t.Fatal(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_read_by_two(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("abc"), 2) | ||||||
|  | 	b := iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if b != 'a' { | ||||||
|  | 		t.Fatal(b) | ||||||
|  | 	} | ||||||
|  | 	b = iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if b != 'b' { | ||||||
|  | 		t.Fatal(b) | ||||||
|  | 	} | ||||||
|  | 	iter.unreadByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	iter.unreadByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	b = iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if b != 'a' { | ||||||
|  | 		t.Fatal(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_read_until_eof(t *testing.T) { | ||||||
|  | 	iter := Parse(bytes.NewBufferString("abc"), 2) | ||||||
|  | 	iter.readByte() | ||||||
|  | 	iter.readByte() | ||||||
|  | 	b := iter.readByte() | ||||||
|  | 	if iter.Error != nil { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | 	if b != 'c' { | ||||||
|  | 		t.Fatal(b) | ||||||
|  | 	} | ||||||
|  | 	iter.readByte() | ||||||
|  | 	if iter.Error != io.EOF { | ||||||
|  | 		t.Fatal(iter.Error) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -7,10 +7,10 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func Test_string_empty(t *testing.T) { | func Test_string_empty(t *testing.T) { | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(`""`), 4096) | 	iter := Parse(bytes.NewBufferString(`""`), 4096) | ||||||
| 	val, err := lexer.LexString() | 	val := iter.ReadString() | ||||||
| 	if err != nil { | 	if iter.Error != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(iter.Error) | ||||||
| 	} | 	} | ||||||
| 	if val != "" { | 	if val != "" { | ||||||
| 		t.Fatal(val) | 		t.Fatal(val) | ||||||
| @@ -18,10 +18,10 @@ func Test_string_empty(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Test_string_hello(t *testing.T) { | func Test_string_hello(t *testing.T) { | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(`"hello"`), 4096) | 	iter := Parse(bytes.NewBufferString(`"hello"`), 4096) | ||||||
| 	val, err := lexer.LexString() | 	val := iter.ReadString() | ||||||
| 	if err != nil { | 	if iter.Error != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(iter.Error) | ||||||
| 	} | 	} | ||||||
| 	if val != "hello" { | 	if val != "hello" { | ||||||
| 		t.Fatal(val) | 		t.Fatal(val) | ||||||
| @@ -29,10 +29,10 @@ func Test_string_hello(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Test_string_escape_quote(t *testing.T) { | func Test_string_escape_quote(t *testing.T) { | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(`"hel\"lo"`), 4096) | 	iter := Parse(bytes.NewBufferString(`"hel\"lo"`), 4096) | ||||||
| 	val, err := lexer.LexString() | 	val := iter.ReadString() | ||||||
| 	if err != nil { | 	if iter.Error != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(iter.Error) | ||||||
| 	} | 	} | ||||||
| 	if val != `hel"lo` { | 	if val != `hel"lo` { | ||||||
| 		t.Fatal(val) | 		t.Fatal(val) | ||||||
| @@ -40,10 +40,10 @@ func Test_string_escape_quote(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Test_string_escape_newline(t *testing.T) { | func Test_string_escape_newline(t *testing.T) { | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(`"hel\nlo"`), 4096) | 	iter := Parse(bytes.NewBufferString(`"hel\nlo"`), 4096) | ||||||
| 	val, err := lexer.LexString() | 	val := iter.ReadString() | ||||||
| 	if err != nil { | 	if iter.Error != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(iter.Error) | ||||||
| 	} | 	} | ||||||
| 	if val != "hel\nlo" { | 	if val != "hel\nlo" { | ||||||
| 		t.Fatal(val) | 		t.Fatal(val) | ||||||
| @@ -51,10 +51,10 @@ func Test_string_escape_newline(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Test_string_escape_unicode(t *testing.T) { | func Test_string_escape_unicode(t *testing.T) { | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(`"\u4e2d\u6587"`), 4096) | 	iter := Parse(bytes.NewBufferString(`"\u4e2d\u6587"`), 4096) | ||||||
| 	val, err := lexer.LexString() | 	val := iter.ReadString() | ||||||
| 	if err != nil { | 	if iter.Error != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(iter.Error) | ||||||
| 	} | 	} | ||||||
| 	if val != "中文" { | 	if val != "中文" { | ||||||
| 		t.Fatal(val) | 		t.Fatal(val) | ||||||
| @@ -62,10 +62,10 @@ func Test_string_escape_unicode(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Test_string_escape_unicode_with_surrogate(t *testing.T) { | func Test_string_escape_unicode_with_surrogate(t *testing.T) { | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(`"\ud83d\udc4a"`), 4096) | 	iter := Parse(bytes.NewBufferString(`"\ud83d\udc4a"`), 4096) | ||||||
| 	val, err := lexer.LexString() | 	val := iter.ReadString() | ||||||
| 	if err != nil { | 	if iter.Error != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(iter.Error) | ||||||
| 	} | 	} | ||||||
| 	if val != "\xf0\x9f\x91\x8a" { | 	if val != "\xf0\x9f\x91\x8a" { | ||||||
| 		t.Fatal(val) | 		t.Fatal(val) | ||||||
| @@ -74,15 +74,15 @@ func Test_string_escape_unicode_with_surrogate(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func Benchmark_jsoniter_unicode(b *testing.B) { | func Benchmark_jsoniter_unicode(b *testing.B) { | ||||||
| 	for n := 0; n < b.N; n++ { | 	for n := 0; n < b.N; n++ { | ||||||
| 		lexer := NewLexerWithArray([]byte(`"\ud83d\udc4a"`)) | 		iter := ParseString(`"\ud83d\udc4a"`) | ||||||
| 		lexer.LexString() | 		iter.ReadString() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Benchmark_jsoniter_ascii(b *testing.B) { | func Benchmark_jsoniter_ascii(b *testing.B) { | ||||||
| 	for n := 0; n < b.N; n++ { | 	for n := 0; n < b.N; n++ { | ||||||
| 		lexer := NewLexerWithArray([]byte(`"hello"`)) | 		iter := ParseString(`"hello"`) | ||||||
| 		lexer.LexString() | 		iter.ReadString() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
							
								
								
									
										254
									
								
								jsoniter_test.go
									
									
									
									
									
								
							
							
						
						
									
										254
									
								
								jsoniter_test.go
									
									
									
									
									
								
							| @@ -1,254 +0,0 @@ | |||||||
| package jsoniter |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func Test_int_1(t *testing.T) { |  | ||||||
| 	iter := NewIterator([]byte("1")) |  | ||||||
| 	val := iter.ReadInt() |  | ||||||
| 	if val != 1 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_int_minus_1(t *testing.T) { |  | ||||||
| 	iter := NewIterator([]byte("-1")) |  | ||||||
| 	val := iter.ReadInt() |  | ||||||
| 	if val != -1 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_int_100(t *testing.T) { |  | ||||||
| 	iter := NewIterator([]byte("100,")) |  | ||||||
| 	val := iter.ReadInt() |  | ||||||
| 	if val != 100 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_int_0(t *testing.T) { |  | ||||||
| 	iter := NewIterator([]byte("0")) |  | ||||||
| 	val := iter.ReadInt() |  | ||||||
| 	if val != 0 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //func Test_single_element(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := 0 |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadInt() |  | ||||||
| //	}) |  | ||||||
| //	if val != 1 { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_multiple_elements(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1, 2]")) |  | ||||||
| //	result := []int{0, 0} |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		result[index] = iter.ReadInt() |  | ||||||
| //	}) |  | ||||||
| //	if !reflect.DeepEqual([]int{1, 2}, result) { |  | ||||||
| //		t.Fatal(result) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_invalid_array(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1, ]")) |  | ||||||
| //	result := []int{0, 0} |  | ||||||
| //	var foundErr error |  | ||||||
| //	iter.ErrorHandler = func(err error) { |  | ||||||
| //		foundErr = err |  | ||||||
| //	} |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		result[index] = iter.ReadInt() |  | ||||||
| //	}) |  | ||||||
| //	if foundErr == nil { |  | ||||||
| //		t.FailNow() |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_single_field(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte(`{"a": 1}`)) |  | ||||||
| //	result := map[string]int{} |  | ||||||
| //	iter.ReadObject(func(iter Iterator, field string) { |  | ||||||
| //		result[field] = iter.ReadInt() |  | ||||||
| //	}) |  | ||||||
| //	if !reflect.DeepEqual(map[string]int{"a": 1}, result) { |  | ||||||
| //		t.Fatal(result) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_multiple_fields(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte(`{"a": 1, "b": 2}`)) |  | ||||||
| //	result := map[string]int{} |  | ||||||
| //	iter.ReadObject(func(iter Iterator, field string) { |  | ||||||
| //		result[field] = iter.ReadInt() |  | ||||||
| //	}) |  | ||||||
| //	if !reflect.DeepEqual(map[string]int{"a": 1, "b": 2}, result) { |  | ||||||
| //		t.Fatal(result) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_nested_object(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte(`{"a": [{"b": 2}, {"b": 1}]}`)) |  | ||||||
| //	obj := map[string][]map[string]int{} |  | ||||||
| //	iter.ReadObject(func(iter Iterator, field string) { |  | ||||||
| //		array := []map[string]int{} |  | ||||||
| //		iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //			nestedObj := map[string]int{} |  | ||||||
| //			iter.ReadObject(func(iter Iterator, field string) { |  | ||||||
| //				nestedObj[field] = iter.ReadInt() |  | ||||||
| //			}) |  | ||||||
| //			array = append(array, nestedObj) |  | ||||||
| //		}) |  | ||||||
| //		obj[field] = array |  | ||||||
| //	}) |  | ||||||
| //	if !reflect.DeepEqual(obj, map[string][]map[string]int{ |  | ||||||
| //		"a": {{"b": 2}, {"b": 1}}, |  | ||||||
| //	}) { |  | ||||||
| //		t.Fatal(obj) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_skip(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte(`{"a": [{"b": 2}, {"b": 1}], "c": 3}`)) |  | ||||||
| //	val := 0 |  | ||||||
| //	iter.ReadObject(func(iter Iterator, field string) { |  | ||||||
| //		if ("c" == field) { |  | ||||||
| //			val = iter.ReadInt() |  | ||||||
| //		} else { |  | ||||||
| //			iter.Skip() |  | ||||||
| //		} |  | ||||||
| //	}) |  | ||||||
| //	if val != 3 { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_int8(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := int8(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadInt8() |  | ||||||
| //	}) |  | ||||||
| //	if val != int8(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_int16(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := int16(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadInt16() |  | ||||||
| //	}) |  | ||||||
| //	if val != int16(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_int32(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := int32(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadInt32() |  | ||||||
| //	}) |  | ||||||
| //	if val != int32(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_int64(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := int64(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadInt64() |  | ||||||
| //	}) |  | ||||||
| //	if val != int64(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_uint(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := uint(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadUint() |  | ||||||
| //	}) |  | ||||||
| //	if val != uint(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_uint8(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := uint8(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadUint8() |  | ||||||
| //	}) |  | ||||||
| //	if val != uint8(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_uint16(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := uint16(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadUint16() |  | ||||||
| //	}) |  | ||||||
| //	if val != uint16(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_uint32(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := uint32(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadUint32() |  | ||||||
| //	}) |  | ||||||
| //	if val != uint32(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_uint64(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1]")) |  | ||||||
| //	val := uint64(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadUint64() |  | ||||||
| //	}) |  | ||||||
| //	if val != uint64(1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_float32(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1.1]")) |  | ||||||
| //	val := float32(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadFloat32() |  | ||||||
| //	}) |  | ||||||
| //	if val != float32(1.1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
| //func Test_float64(t *testing.T) { |  | ||||||
| //	iter := NewIterator([]byte("[1.1]")) |  | ||||||
| //	val := float64(0) |  | ||||||
| //	iter.ReadArray(func(iter Iterator, index int) { |  | ||||||
| //		val = iter.ReadFloat64() |  | ||||||
| //	}) |  | ||||||
| //	if val != float64(1.1) { |  | ||||||
| //		t.Fatal(val) |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
| // |  | ||||||
							
								
								
									
										276
									
								
								lexer.go
									
									
									
									
									
								
							
							
						
						
									
										276
									
								
								lexer.go
									
									
									
									
									
								
							| @@ -1,276 +0,0 @@ | |||||||
| package jsoniter |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"io" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"unicode/utf16" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type Lexer struct { |  | ||||||
| 	reader io.Reader |  | ||||||
| 	buf    []byte |  | ||||||
| 	head   int |  | ||||||
| 	tail   int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewLexer(reader io.Reader, bufSize int) *Lexer { |  | ||||||
| 	return &Lexer{ |  | ||||||
| 		reader: reader, |  | ||||||
| 		buf: make([]byte, bufSize), |  | ||||||
| 		head: 0, |  | ||||||
| 		tail: 0, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewLexerWithArray(input []byte) *Lexer { |  | ||||||
| 	return &Lexer{ |  | ||||||
| 		reader: nil, |  | ||||||
| 		buf: input, |  | ||||||
| 		head: 0, |  | ||||||
| 		tail: len(input), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (lexer *Lexer) readByte() (byte, error) { |  | ||||||
| 	if lexer.head == lexer.tail { |  | ||||||
| 		if lexer.reader == nil { |  | ||||||
| 			return 0, io.EOF |  | ||||||
| 		} |  | ||||||
| 		n, err := lexer.reader.Read(lexer.buf) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		if n == 0 { |  | ||||||
| 			return 0, io.EOF |  | ||||||
| 		} |  | ||||||
| 		lexer.head = 0 |  | ||||||
| 		lexer.tail = n |  | ||||||
| 	} |  | ||||||
| 	b := lexer.buf[lexer.head] |  | ||||||
| 	lexer.head += 1 |  | ||||||
| 	return b, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (lexer *Lexer) unreadByte() error { |  | ||||||
| 	if lexer.head == 0 { |  | ||||||
| 		return errors.New("unread too many bytes") |  | ||||||
| 	} |  | ||||||
| 	lexer.head -= 1 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const maxUint64 = (1 << 64 - 1) |  | ||||||
| const cutoffUint64 = maxUint64 / 10 + 1 |  | ||||||
| const maxUint32 = (1 << 32 - 1) |  | ||||||
| const cutoffUint32 = maxUint32 / 10 + 1 |  | ||||||
|  |  | ||||||
| func (lexer *Lexer) LexUin64() (uint64, error) { |  | ||||||
| 	var n uint64 |  | ||||||
| 	c, err := lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* a single zero, or a series of integers */ |  | ||||||
| 	if c == '0' { |  | ||||||
| 		c, err = lexer.readByte() |  | ||||||
| 		if err != nil && err != io.EOF { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 	} else if c >= '1' && c <= '9' { |  | ||||||
| 		for c >= '0' && c <= '9' { |  | ||||||
| 			var v byte |  | ||||||
| 			v = c - '0' |  | ||||||
| 			if n >= cutoffUint64 { |  | ||||||
| 				return 0, errors.New("overflow") |  | ||||||
| 			} |  | ||||||
| 			n = n * uint64(10) + uint64(v) |  | ||||||
| 			c, err = lexer.readByte() |  | ||||||
| 			if err != nil && err != io.EOF { |  | ||||||
| 				return 0, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		lexer.unreadByte() |  | ||||||
| 	} else { |  | ||||||
| 		lexer.unreadByte() |  | ||||||
| 		return 0, errors.New("unexpected") |  | ||||||
| 	} |  | ||||||
| 	return n, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (lexer *Lexer) LexInt64() (int64, error) { |  | ||||||
| 	c, err := lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* optional leading minus */ |  | ||||||
| 	if c == '-' { |  | ||||||
| 		n, err := lexer.LexUin64() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		return -int64(n), nil |  | ||||||
| 	} else { |  | ||||||
| 		lexer.unreadByte() |  | ||||||
| 		n, err := lexer.LexUin64() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		return int64(n), nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (lexer *Lexer) LexString() (string, error) { |  | ||||||
| 	str := make([]byte, 0, 10) |  | ||||||
| 	c, err := lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 	if c != '"' { |  | ||||||
| 		return "", errors.New("unexpected") |  | ||||||
| 	} |  | ||||||
| 	for { |  | ||||||
| 		c, err = lexer.readByte() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return "", err |  | ||||||
| 		} |  | ||||||
| 		switch c { |  | ||||||
| 		case '\\': |  | ||||||
| 			c, err = lexer.readByte() |  | ||||||
| 			if err != nil { |  | ||||||
| 				return "", err |  | ||||||
| 			} |  | ||||||
| 			switch c { |  | ||||||
| 			case 'u': |  | ||||||
| 				r, err := lexer.readU4() |  | ||||||
| 				if err != nil { |  | ||||||
| 					return "", err |  | ||||||
| 				} |  | ||||||
| 				if utf16.IsSurrogate(r) { |  | ||||||
| 					c, err = lexer.readByte() |  | ||||||
| 					if err != nil { |  | ||||||
| 						return "", err |  | ||||||
| 					} |  | ||||||
| 					if c != '\\' { |  | ||||||
| 						return "", fmt.Errorf("unexpected: %v", c) |  | ||||||
| 					} |  | ||||||
| 					c, err = lexer.readByte() |  | ||||||
| 					if err != nil { |  | ||||||
| 						return "", err |  | ||||||
| 					} |  | ||||||
| 					if c != 'u' { |  | ||||||
| 						return "", fmt.Errorf("unexpected: %v", c) |  | ||||||
| 					} |  | ||||||
| 					r2, err := lexer.readU4() |  | ||||||
| 					if err != nil { |  | ||||||
| 						return "", err |  | ||||||
| 					} |  | ||||||
| 					combined := utf16.DecodeRune(r, r2) |  | ||||||
| 					str = appendRune(str, combined) |  | ||||||
| 				} else { |  | ||||||
| 					str = appendRune(str, r) |  | ||||||
| 				} |  | ||||||
| 			case '"': |  | ||||||
| 				str = append(str, '"') |  | ||||||
| 			case '\\': |  | ||||||
| 				str = append(str, '\\') |  | ||||||
| 			case '/': |  | ||||||
| 				str = append(str, '/') |  | ||||||
| 			case 'b': |  | ||||||
| 				str = append(str, '\b') |  | ||||||
| 			case 'f': |  | ||||||
| 				str = append(str, '\f') |  | ||||||
| 			case 'n': |  | ||||||
| 				str = append(str, '\n') |  | ||||||
| 			case 'r': |  | ||||||
| 				str = append(str, '\r') |  | ||||||
| 			case 't': |  | ||||||
| 				str = append(str, '\t') |  | ||||||
| 			default: |  | ||||||
| 				return "", errors.New("unexpected") |  | ||||||
| 			} |  | ||||||
| 		case '"': |  | ||||||
| 			return string(str), nil |  | ||||||
| 		default: |  | ||||||
| 			str = append(str, c) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (lexer *Lexer) readU4() (rune, error) { |  | ||||||
| 	var u4 rune |  | ||||||
| 	for i := 0; i < 4; i++ { |  | ||||||
| 		c, err := lexer.readByte() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		if (c >= '0' && c <= '9') { |  | ||||||
| 			if u4 >= cutoffUint32 { |  | ||||||
| 				return 0, errors.New("overflow") |  | ||||||
| 			} |  | ||||||
| 			u4 = u4 * 16 + rune(c - '0') |  | ||||||
| 		} else if ((c >= 'a' && c <= 'f') ) { |  | ||||||
| 			if u4 >= cutoffUint32 { |  | ||||||
| 				return 0, errors.New("overflow") |  | ||||||
| 			} |  | ||||||
| 			u4 = u4 * 16 + rune(c - 'a' + 10) |  | ||||||
| 		} else { |  | ||||||
| 			return 0, fmt.Errorf("unexpected: %v", c) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return u4, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	t1 = 0x00 // 0000 0000 |  | ||||||
| 	tx = 0x80 // 1000 0000 |  | ||||||
| 	t2 = 0xC0 // 1100 0000 |  | ||||||
| 	t3 = 0xE0 // 1110 0000 |  | ||||||
| 	t4 = 0xF0 // 1111 0000 |  | ||||||
| 	t5 = 0xF8 // 1111 1000 |  | ||||||
|  |  | ||||||
| 	maskx = 0x3F // 0011 1111 |  | ||||||
| 	mask2 = 0x1F // 0001 1111 |  | ||||||
| 	mask3 = 0x0F // 0000 1111 |  | ||||||
| 	mask4 = 0x07 // 0000 0111 |  | ||||||
|  |  | ||||||
| 	rune1Max = 1 << 7 - 1 |  | ||||||
| 	rune2Max = 1 << 11 - 1 |  | ||||||
| 	rune3Max = 1 << 16 - 1 |  | ||||||
|  |  | ||||||
| 	surrogateMin = 0xD800 |  | ||||||
| 	surrogateMax = 0xDFFF |  | ||||||
|  |  | ||||||
| 	MaxRune = '\U0010FFFF' // Maximum valid Unicode code point. |  | ||||||
| 	RuneError = '\uFFFD'     // the "error" Rune or "Unicode replacement character" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func appendRune(p []byte, r rune) []byte { |  | ||||||
| 	// Negative values are erroneous. Making it unsigned addresses the problem. |  | ||||||
| 	switch i := uint32(r); { |  | ||||||
| 	case i <= rune1Max: |  | ||||||
| 		p = append(p, byte(r)) |  | ||||||
| 		return p |  | ||||||
| 	case i <= rune2Max: |  | ||||||
| 		p = append(p, t2 | byte(r >> 6)) |  | ||||||
| 		p = append(p, tx | byte(r) & maskx) |  | ||||||
| 		return p |  | ||||||
| 	case i > MaxRune, surrogateMin <= i && i <= surrogateMax: |  | ||||||
| 		r = RuneError |  | ||||||
| 		fallthrough |  | ||||||
| 	case i <= rune3Max: |  | ||||||
| 		p = append(p, t3 | byte(r >> 12)) |  | ||||||
| 		p = append(p, tx | byte(r >> 6) & maskx) |  | ||||||
| 		p = append(p, tx | byte(r) & maskx) |  | ||||||
| 		return p |  | ||||||
| 	default: |  | ||||||
| 		p = append(p, t4 | byte(r >> 18)) |  | ||||||
| 		p = append(p, tx | byte(r >> 12) & maskx) |  | ||||||
| 		p = append(p, tx | byte(r >> 6) & maskx) |  | ||||||
| 		p = append(p, tx | byte(r) & maskx) |  | ||||||
| 		return p |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| @@ -1,95 +0,0 @@ | |||||||
| package jsoniter |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"testing" |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/json" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func Test_uint64_0(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("0"), 4096) |  | ||||||
| 	val, err := lexer.LexUin64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if val != 0 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_uint64_1(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("1"), 4096) |  | ||||||
| 	val, err := lexer.LexUin64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if val != 1 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_uint64_100(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("100"), 4096) |  | ||||||
| 	val, err := lexer.LexUin64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if val != 100 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_uint64_100_comma(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("100,"), 4096) |  | ||||||
| 	val, err := lexer.LexUin64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if val != 100 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_uint64_invalid(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString(","), 4096) |  | ||||||
| 	_, err := lexer.LexUin64() |  | ||||||
| 	if err == nil { |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_int64_100(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("100"), 4096) |  | ||||||
| 	val, err := lexer.LexInt64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if val != 100 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_int64_minus_100(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("-100"), 4096) |  | ||||||
| 	val, err := lexer.LexInt64() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if val != -100 { |  | ||||||
| 		t.Fatal(val) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Benchmark_jsoniter_int(b *testing.B) { |  | ||||||
| 	for n := 0; n < b.N; n++ { |  | ||||||
| 		lexer := NewLexerWithArray([]byte(`-100`)) |  | ||||||
| 		lexer.LexInt64() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Benchmark_json_int(b *testing.B) { |  | ||||||
| 	for n := 0; n < b.N; n++ { |  | ||||||
| 		result := int64(0) |  | ||||||
| 		json.Unmarshal([]byte(`-100`), &result) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -1,83 +0,0 @@ | |||||||
| package jsoniter |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"testing" |  | ||||||
| 	"bytes" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func Test_read_by_one(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("abc"), 1) |  | ||||||
| 	b, err := lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if b != 'a' { |  | ||||||
| 		t.Fatal(b) |  | ||||||
| 	} |  | ||||||
| 	err = lexer.unreadByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	err = lexer.unreadByte() |  | ||||||
| 	if err == nil { |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 	b, err = lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if b != 'a' { |  | ||||||
| 		t.Fatal(b) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_read_by_two(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("abc"), 2) |  | ||||||
| 	b, err := lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if b != 'a' { |  | ||||||
| 		t.Fatal(b) |  | ||||||
| 	} |  | ||||||
| 	b, err = lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if b != 'b' { |  | ||||||
| 		t.Fatal(b) |  | ||||||
| 	} |  | ||||||
| 	err = lexer.unreadByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	err = lexer.unreadByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	b, err = lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if b != 'a' { |  | ||||||
| 		t.Fatal(b) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Test_read_until_eof(t *testing.T) { |  | ||||||
| 	lexer := NewLexer(bytes.NewBufferString("abc"), 2) |  | ||||||
| 	lexer.readByte() |  | ||||||
| 	lexer.readByte() |  | ||||||
| 	b, err := lexer.readByte() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if b != 'c' { |  | ||||||
| 		t.Fatal(b) |  | ||||||
| 	} |  | ||||||
| 	_, err = lexer.readByte() |  | ||||||
| 	if err != io.EOF { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										202
									
								
								vendor/github.com/pquerna/ffjson/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/pquerna/ffjson/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,202 +0,0 @@ | |||||||
|  |  | ||||||
|                                  Apache License |  | ||||||
|                            Version 2.0, January 2004 |  | ||||||
|                         http://www.apache.org/licenses/ |  | ||||||
|  |  | ||||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |  | ||||||
|  |  | ||||||
|    1. Definitions. |  | ||||||
|  |  | ||||||
|       "License" shall mean the terms and conditions for use, reproduction, |  | ||||||
|       and distribution as defined by Sections 1 through 9 of this document. |  | ||||||
|  |  | ||||||
|       "Licensor" shall mean the copyright owner or entity authorized by |  | ||||||
|       the copyright owner that is granting the License. |  | ||||||
|  |  | ||||||
|       "Legal Entity" shall mean the union of the acting entity and all |  | ||||||
|       other entities that control, are controlled by, or are under common |  | ||||||
|       control with that entity. For the purposes of this definition, |  | ||||||
|       "control" means (i) the power, direct or indirect, to cause the |  | ||||||
|       direction or management of such entity, whether by contract or |  | ||||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the |  | ||||||
|       outstanding shares, or (iii) beneficial ownership of such entity. |  | ||||||
|  |  | ||||||
|       "You" (or "Your") shall mean an individual or Legal Entity |  | ||||||
|       exercising permissions granted by this License. |  | ||||||
|  |  | ||||||
|       "Source" form shall mean the preferred form for making modifications, |  | ||||||
|       including but not limited to software source code, documentation |  | ||||||
|       source, and configuration files. |  | ||||||
|  |  | ||||||
|       "Object" form shall mean any form resulting from mechanical |  | ||||||
|       transformation or translation of a Source form, including but |  | ||||||
|       not limited to compiled object code, generated documentation, |  | ||||||
|       and conversions to other media types. |  | ||||||
|  |  | ||||||
|       "Work" shall mean the work of authorship, whether in Source or |  | ||||||
|       Object form, made available under the License, as indicated by a |  | ||||||
|       copyright notice that is included in or attached to the work |  | ||||||
|       (an example is provided in the Appendix below). |  | ||||||
|  |  | ||||||
|       "Derivative Works" shall mean any work, whether in Source or Object |  | ||||||
|       form, that is based on (or derived from) the Work and for which the |  | ||||||
|       editorial revisions, annotations, elaborations, or other modifications |  | ||||||
|       represent, as a whole, an original work of authorship. For the purposes |  | ||||||
|       of this License, Derivative Works shall not include works that remain |  | ||||||
|       separable from, or merely link (or bind by name) to the interfaces of, |  | ||||||
|       the Work and Derivative Works thereof. |  | ||||||
|  |  | ||||||
|       "Contribution" shall mean any work of authorship, including |  | ||||||
|       the original version of the Work and any modifications or additions |  | ||||||
|       to that Work or Derivative Works thereof, that is intentionally |  | ||||||
|       submitted to Licensor for inclusion in the Work by the copyright owner |  | ||||||
|       or by an individual or Legal Entity authorized to submit on behalf of |  | ||||||
|       the copyright owner. For the purposes of this definition, "submitted" |  | ||||||
|       means any form of electronic, verbal, or written communication sent |  | ||||||
|       to the Licensor or its representatives, including but not limited to |  | ||||||
|       communication on electronic mailing lists, source code control systems, |  | ||||||
|       and issue tracking systems that are managed by, or on behalf of, the |  | ||||||
|       Licensor for the purpose of discussing and improving the Work, but |  | ||||||
|       excluding communication that is conspicuously marked or otherwise |  | ||||||
|       designated in writing by the copyright owner as "Not a Contribution." |  | ||||||
|  |  | ||||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity |  | ||||||
|       on behalf of whom a Contribution has been received by Licensor and |  | ||||||
|       subsequently incorporated within the Work. |  | ||||||
|  |  | ||||||
|    2. Grant of Copyright License. Subject to the terms and conditions of |  | ||||||
|       this License, each Contributor hereby grants to You a perpetual, |  | ||||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable |  | ||||||
|       copyright license to reproduce, prepare Derivative Works of, |  | ||||||
|       publicly display, publicly perform, sublicense, and distribute the |  | ||||||
|       Work and such Derivative Works in Source or Object form. |  | ||||||
|  |  | ||||||
|    3. Grant of Patent License. Subject to the terms and conditions of |  | ||||||
|       this License, each Contributor hereby grants to You a perpetual, |  | ||||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable |  | ||||||
|       (except as stated in this section) patent license to make, have made, |  | ||||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, |  | ||||||
|       where such license applies only to those patent claims licensable |  | ||||||
|       by such Contributor that are necessarily infringed by their |  | ||||||
|       Contribution(s) alone or by combination of their Contribution(s) |  | ||||||
|       with the Work to which such Contribution(s) was submitted. If You |  | ||||||
|       institute patent litigation against any entity (including a |  | ||||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work |  | ||||||
|       or a Contribution incorporated within the Work constitutes direct |  | ||||||
|       or contributory patent infringement, then any patent licenses |  | ||||||
|       granted to You under this License for that Work shall terminate |  | ||||||
|       as of the date such litigation is filed. |  | ||||||
|  |  | ||||||
|    4. Redistribution. You may reproduce and distribute copies of the |  | ||||||
|       Work or Derivative Works thereof in any medium, with or without |  | ||||||
|       modifications, and in Source or Object form, provided that You |  | ||||||
|       meet the following conditions: |  | ||||||
|  |  | ||||||
|       (a) You must give any other recipients of the Work or |  | ||||||
|           Derivative Works a copy of this License; and |  | ||||||
|  |  | ||||||
|       (b) You must cause any modified files to carry prominent notices |  | ||||||
|           stating that You changed the files; and |  | ||||||
|  |  | ||||||
|       (c) You must retain, in the Source form of any Derivative Works |  | ||||||
|           that You distribute, all copyright, patent, trademark, and |  | ||||||
|           attribution notices from the Source form of the Work, |  | ||||||
|           excluding those notices that do not pertain to any part of |  | ||||||
|           the Derivative Works; and |  | ||||||
|  |  | ||||||
|       (d) If the Work includes a "NOTICE" text file as part of its |  | ||||||
|           distribution, then any Derivative Works that You distribute must |  | ||||||
|           include a readable copy of the attribution notices contained |  | ||||||
|           within such NOTICE file, excluding those notices that do not |  | ||||||
|           pertain to any part of the Derivative Works, in at least one |  | ||||||
|           of the following places: within a NOTICE text file distributed |  | ||||||
|           as part of the Derivative Works; within the Source form or |  | ||||||
|           documentation, if provided along with the Derivative Works; or, |  | ||||||
|           within a display generated by the Derivative Works, if and |  | ||||||
|           wherever such third-party notices normally appear. The contents |  | ||||||
|           of the NOTICE file are for informational purposes only and |  | ||||||
|           do not modify the License. You may add Your own attribution |  | ||||||
|           notices within Derivative Works that You distribute, alongside |  | ||||||
|           or as an addendum to the NOTICE text from the Work, provided |  | ||||||
|           that such additional attribution notices cannot be construed |  | ||||||
|           as modifying the License. |  | ||||||
|  |  | ||||||
|       You may add Your own copyright statement to Your modifications and |  | ||||||
|       may provide additional or different license terms and conditions |  | ||||||
|       for use, reproduction, or distribution of Your modifications, or |  | ||||||
|       for any such Derivative Works as a whole, provided Your use, |  | ||||||
|       reproduction, and distribution of the Work otherwise complies with |  | ||||||
|       the conditions stated in this License. |  | ||||||
|  |  | ||||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, |  | ||||||
|       any Contribution intentionally submitted for inclusion in the Work |  | ||||||
|       by You to the Licensor shall be under the terms and conditions of |  | ||||||
|       this License, without any additional terms or conditions. |  | ||||||
|       Notwithstanding the above, nothing herein shall supersede or modify |  | ||||||
|       the terms of any separate license agreement you may have executed |  | ||||||
|       with Licensor regarding such Contributions. |  | ||||||
|  |  | ||||||
|    6. Trademarks. This License does not grant permission to use the trade |  | ||||||
|       names, trademarks, service marks, or product names of the Licensor, |  | ||||||
|       except as required for reasonable and customary use in describing the |  | ||||||
|       origin of the Work and reproducing the content of the NOTICE file. |  | ||||||
|  |  | ||||||
|    7. Disclaimer of Warranty. Unless required by applicable law or |  | ||||||
|       agreed to in writing, Licensor provides the Work (and each |  | ||||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, |  | ||||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |  | ||||||
|       implied, including, without limitation, any warranties or conditions |  | ||||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |  | ||||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the |  | ||||||
|       appropriateness of using or redistributing the Work and assume any |  | ||||||
|       risks associated with Your exercise of permissions under this License. |  | ||||||
|  |  | ||||||
|    8. Limitation of Liability. In no event and under no legal theory, |  | ||||||
|       whether in tort (including negligence), contract, or otherwise, |  | ||||||
|       unless required by applicable law (such as deliberate and grossly |  | ||||||
|       negligent acts) or agreed to in writing, shall any Contributor be |  | ||||||
|       liable to You for damages, including any direct, indirect, special, |  | ||||||
|       incidental, or consequential damages of any character arising as a |  | ||||||
|       result of this License or out of the use or inability to use the |  | ||||||
|       Work (including but not limited to damages for loss of goodwill, |  | ||||||
|       work stoppage, computer failure or malfunction, or any and all |  | ||||||
|       other commercial damages or losses), even if such Contributor |  | ||||||
|       has been advised of the possibility of such damages. |  | ||||||
|  |  | ||||||
|    9. Accepting Warranty or Additional Liability. While redistributing |  | ||||||
|       the Work or Derivative Works thereof, You may choose to offer, |  | ||||||
|       and charge a fee for, acceptance of support, warranty, indemnity, |  | ||||||
|       or other liability obligations and/or rights consistent with this |  | ||||||
|       License. However, in accepting such obligations, You may act only |  | ||||||
|       on Your own behalf and on Your sole responsibility, not on behalf |  | ||||||
|       of any other Contributor, and only if You agree to indemnify, |  | ||||||
|       defend, and hold each Contributor harmless for any liability |  | ||||||
|       incurred by, or claims asserted against, such Contributor by reason |  | ||||||
|       of your accepting any such warranty or additional liability. |  | ||||||
|  |  | ||||||
|    END OF TERMS AND CONDITIONS |  | ||||||
|  |  | ||||||
|    APPENDIX: How to apply the Apache License to your work. |  | ||||||
|  |  | ||||||
|       To apply the Apache License to your work, attach the following |  | ||||||
|       boilerplate notice, with the fields enclosed by brackets "[]" |  | ||||||
|       replaced with your own identifying information. (Don't include |  | ||||||
|       the brackets!)  The text should be enclosed in the appropriate |  | ||||||
|       comment syntax for the file format. We also recommend that a |  | ||||||
|       file or class name and description of purpose be included on the |  | ||||||
|       same "printed page" as the copyright notice for easier |  | ||||||
|       identification within third-party archives. |  | ||||||
|  |  | ||||||
|    Copyright [yyyy] [name of copyright owner] |  | ||||||
|  |  | ||||||
|    Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|    you may not use this file except in compliance with the License. |  | ||||||
|    You may obtain a copy of the License at |  | ||||||
|  |  | ||||||
|        http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  |  | ||||||
|    Unless required by applicable law or agreed to in writing, software |  | ||||||
|    distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|    See the License for the specific language governing permissions and |  | ||||||
|    limitations under the License. |  | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/pquerna/ffjson/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/pquerna/ffjson/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +0,0 @@ | |||||||
| ffjson |  | ||||||
| Copyright (c) 2014, Paul Querna |  | ||||||
|  |  | ||||||
| This product includes software developed by  |  | ||||||
| Paul Querna (http://paul.querna.org/). |  | ||||||
|  |  | ||||||
| Portions of this software were developed as |  | ||||||
| part of Go, Copyright (c) 2012 The Go Authors. |  | ||||||
							
								
								
									
										421
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										421
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,421 +0,0 @@ | |||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| // Simple byte buffer for marshaling data. |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| 	"unicode/utf8" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type grower interface { |  | ||||||
| 	Grow(n int) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type truncater interface { |  | ||||||
| 	Truncate(n int) |  | ||||||
| 	Reset() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type bytesReader interface { |  | ||||||
| 	Bytes() []byte |  | ||||||
| 	String() string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type runeWriter interface { |  | ||||||
| 	WriteRune(r rune) (n int, err error) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type stringWriter interface { |  | ||||||
| 	WriteString(s string) (n int, err error) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type lener interface { |  | ||||||
| 	Len() int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type rewinder interface { |  | ||||||
| 	Rewind(n int) (err error) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type encoder interface { |  | ||||||
| 	Encode(interface{}) error |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO(pquerna): continue to reduce these interfaces |  | ||||||
|  |  | ||||||
| type EncodingBuffer interface { |  | ||||||
| 	io.Writer |  | ||||||
| 	io.WriterTo |  | ||||||
| 	io.ByteWriter |  | ||||||
| 	stringWriter |  | ||||||
| 	truncater |  | ||||||
| 	grower |  | ||||||
| 	rewinder |  | ||||||
| 	encoder |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type DecodingBuffer interface { |  | ||||||
| 	io.ReadWriter |  | ||||||
| 	io.ByteWriter |  | ||||||
| 	stringWriter |  | ||||||
| 	runeWriter |  | ||||||
| 	truncater |  | ||||||
| 	grower |  | ||||||
| 	bytesReader |  | ||||||
| 	lener |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // A Buffer is a variable-sized buffer of bytes with Read and Write methods. |  | ||||||
| // The zero value for Buffer is an empty buffer ready to use. |  | ||||||
| type Buffer struct { |  | ||||||
| 	buf              []byte            // contents are the bytes buf[off : len(buf)] |  | ||||||
| 	off              int               // read at &buf[off], write at &buf[len(buf)] |  | ||||||
| 	runeBytes        [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune |  | ||||||
| 	encoder          *json.Encoder |  | ||||||
| 	skipTrailingByte bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer. |  | ||||||
| var ErrTooLarge = errors.New("fflib.v1.Buffer: too large") |  | ||||||
|  |  | ||||||
| // Bytes returns a slice of the contents of the unread portion of the buffer; |  | ||||||
| // len(b.Bytes()) == b.Len().  If the caller changes the contents of the |  | ||||||
| // returned slice, the contents of the buffer will change provided there |  | ||||||
| // are no intervening method calls on the Buffer. |  | ||||||
| func (b *Buffer) Bytes() []byte { return b.buf[b.off:] } |  | ||||||
|  |  | ||||||
| // String returns the contents of the unread portion of the buffer |  | ||||||
| // as a string.  If the Buffer is a nil pointer, it returns "<nil>". |  | ||||||
| func (b *Buffer) String() string { |  | ||||||
| 	if b == nil { |  | ||||||
| 		// Special case, useful in debugging. |  | ||||||
| 		return "<nil>" |  | ||||||
| 	} |  | ||||||
| 	return string(b.buf[b.off:]) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Len returns the number of bytes of the unread portion of the buffer; |  | ||||||
| // b.Len() == len(b.Bytes()). |  | ||||||
| func (b *Buffer) Len() int { return len(b.buf) - b.off } |  | ||||||
|  |  | ||||||
| // Truncate discards all but the first n unread bytes from the buffer. |  | ||||||
| // It panics if n is negative or greater than the length of the buffer. |  | ||||||
| func (b *Buffer) Truncate(n int) { |  | ||||||
| 	if n == 0 { |  | ||||||
| 		b.off = 0 |  | ||||||
| 		b.buf = b.buf[0:0] |  | ||||||
| 	} else { |  | ||||||
| 		b.buf = b.buf[0 : b.off+n] |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Reset resets the buffer so it has no content. |  | ||||||
| // b.Reset() is the same as b.Truncate(0). |  | ||||||
| func (b *Buffer) Reset() { b.Truncate(0) } |  | ||||||
|  |  | ||||||
| // grow grows the buffer to guarantee space for n more bytes. |  | ||||||
| // It returns the index where bytes should be written. |  | ||||||
| // If the buffer can't grow it will panic with ErrTooLarge. |  | ||||||
| func (b *Buffer) grow(n int) int { |  | ||||||
| 	// If we have no buffer, get one from the pool |  | ||||||
| 	m := b.Len() |  | ||||||
| 	if m == 0 { |  | ||||||
| 		if b.buf == nil { |  | ||||||
| 			b.buf = makeSlice(2 * n) |  | ||||||
| 			b.off = 0 |  | ||||||
| 		} else if b.off != 0 { |  | ||||||
| 			// If buffer is empty, reset to recover space. |  | ||||||
| 			b.Truncate(0) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if len(b.buf)+n > cap(b.buf) { |  | ||||||
| 		var buf []byte |  | ||||||
| 		if m+n <= cap(b.buf)/2 { |  | ||||||
| 			// We can slide things down instead of allocating a new |  | ||||||
| 			// slice. We only need m+n <= cap(b.buf) to slide, but |  | ||||||
| 			// we instead let capacity get twice as large so we |  | ||||||
| 			// don't spend all our time copying. |  | ||||||
| 			copy(b.buf[:], b.buf[b.off:]) |  | ||||||
| 			buf = b.buf[:m] |  | ||||||
| 		} else { |  | ||||||
| 			// not enough space anywhere |  | ||||||
| 			buf = makeSlice(2*cap(b.buf) + n) |  | ||||||
| 			copy(buf, b.buf[b.off:]) |  | ||||||
| 		} |  | ||||||
| 		Pool(b.buf) |  | ||||||
| 		b.buf = buf |  | ||||||
| 		b.off = 0 |  | ||||||
| 	} |  | ||||||
| 	b.buf = b.buf[0 : b.off+m+n] |  | ||||||
| 	return b.off + m |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Grow grows the buffer's capacity, if necessary, to guarantee space for |  | ||||||
| // another n bytes. After Grow(n), at least n bytes can be written to the |  | ||||||
| // buffer without another allocation. |  | ||||||
| // If n is negative, Grow will panic. |  | ||||||
| // If the buffer can't grow it will panic with ErrTooLarge. |  | ||||||
| func (b *Buffer) Grow(n int) { |  | ||||||
| 	if n < 0 { |  | ||||||
| 		panic("bytes.Buffer.Grow: negative count") |  | ||||||
| 	} |  | ||||||
| 	m := b.grow(n) |  | ||||||
| 	b.buf = b.buf[0:m] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Write appends the contents of p to the buffer, growing the buffer as |  | ||||||
| // needed. The return value n is the length of p; err is always nil. If the |  | ||||||
| // buffer becomes too large, Write will panic with ErrTooLarge. |  | ||||||
| func (b *Buffer) Write(p []byte) (n int, err error) { |  | ||||||
| 	if b.skipTrailingByte { |  | ||||||
| 		p = p[:len(p)-1] |  | ||||||
| 	} |  | ||||||
| 	m := b.grow(len(p)) |  | ||||||
| 	return copy(b.buf[m:], p), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // WriteString appends the contents of s to the buffer, growing the buffer as |  | ||||||
| // needed. The return value n is the length of s; err is always nil. If the |  | ||||||
| // buffer becomes too large, WriteString will panic with ErrTooLarge. |  | ||||||
| func (b *Buffer) WriteString(s string) (n int, err error) { |  | ||||||
| 	m := b.grow(len(s)) |  | ||||||
| 	return copy(b.buf[m:], s), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MinRead is the minimum slice size passed to a Read call by |  | ||||||
| // Buffer.ReadFrom.  As long as the Buffer has at least MinRead bytes beyond |  | ||||||
| // what is required to hold the contents of r, ReadFrom will not grow the |  | ||||||
| // underlying buffer. |  | ||||||
| const minRead = 512 |  | ||||||
|  |  | ||||||
| // ReadFrom reads data from r until EOF and appends it to the buffer, growing |  | ||||||
| // the buffer as needed. The return value n is the number of bytes read. Any |  | ||||||
| // error except io.EOF encountered during the read is also returned. If the |  | ||||||
| // buffer becomes too large, ReadFrom will panic with ErrTooLarge. |  | ||||||
| func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) { |  | ||||||
| 	// If buffer is empty, reset to recover space. |  | ||||||
| 	if b.off >= len(b.buf) { |  | ||||||
| 		b.Truncate(0) |  | ||||||
| 	} |  | ||||||
| 	for { |  | ||||||
| 		if free := cap(b.buf) - len(b.buf); free < minRead { |  | ||||||
| 			// not enough space at end |  | ||||||
| 			newBuf := b.buf |  | ||||||
| 			if b.off+free < minRead { |  | ||||||
| 				// not enough space using beginning of buffer; |  | ||||||
| 				// double buffer capacity |  | ||||||
| 				newBuf = makeSlice(2*cap(b.buf) + minRead) |  | ||||||
| 			} |  | ||||||
| 			copy(newBuf, b.buf[b.off:]) |  | ||||||
| 			Pool(b.buf) |  | ||||||
| 			b.buf = newBuf[:len(b.buf)-b.off] |  | ||||||
| 			b.off = 0 |  | ||||||
| 		} |  | ||||||
| 		m, e := r.Read(b.buf[len(b.buf):cap(b.buf)]) |  | ||||||
| 		b.buf = b.buf[0 : len(b.buf)+m] |  | ||||||
| 		n += int64(m) |  | ||||||
| 		if e == io.EOF { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		if e != nil { |  | ||||||
| 			return n, e |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return n, nil // err is EOF, so return nil explicitly |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // WriteTo writes data to w until the buffer is drained or an error occurs. |  | ||||||
| // The return value n is the number of bytes written; it always fits into an |  | ||||||
| // int, but it is int64 to match the io.WriterTo interface. Any error |  | ||||||
| // encountered during the write is also returned. |  | ||||||
| func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) { |  | ||||||
| 	if b.off < len(b.buf) { |  | ||||||
| 		nBytes := b.Len() |  | ||||||
| 		m, e := w.Write(b.buf[b.off:]) |  | ||||||
| 		if m > nBytes { |  | ||||||
| 			panic("bytes.Buffer.WriteTo: invalid Write count") |  | ||||||
| 		} |  | ||||||
| 		b.off += m |  | ||||||
| 		n = int64(m) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return n, e |  | ||||||
| 		} |  | ||||||
| 		// all bytes should have been written, by definition of |  | ||||||
| 		// Write method in io.Writer |  | ||||||
| 		if m != nBytes { |  | ||||||
| 			return n, io.ErrShortWrite |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	// Buffer is now empty; reset. |  | ||||||
| 	b.Truncate(0) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // WriteByte appends the byte c to the buffer, growing the buffer as needed. |  | ||||||
| // The returned error is always nil, but is included to match bufio.Writer's |  | ||||||
| // WriteByte. If the buffer becomes too large, WriteByte will panic with |  | ||||||
| // ErrTooLarge. |  | ||||||
| func (b *Buffer) WriteByte(c byte) error { |  | ||||||
| 	m := b.grow(1) |  | ||||||
| 	b.buf[m] = c |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (b *Buffer) Rewind(n int) error { |  | ||||||
| 	b.buf = b.buf[:len(b.buf)-n] |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (b *Buffer) Encode(v interface{}) error { |  | ||||||
| 	if b.encoder == nil { |  | ||||||
| 		b.encoder = json.NewEncoder(b) |  | ||||||
| 	} |  | ||||||
| 	b.skipTrailingByte = true |  | ||||||
| 	err := b.encoder.Encode(v) |  | ||||||
| 	b.skipTrailingByte = false |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // WriteRune appends the UTF-8 encoding of Unicode code point r to the |  | ||||||
| // buffer, returning its length and an error, which is always nil but is |  | ||||||
| // included to match bufio.Writer's WriteRune. The buffer is grown as needed; |  | ||||||
| // if it becomes too large, WriteRune will panic with ErrTooLarge. |  | ||||||
| func (b *Buffer) WriteRune(r rune) (n int, err error) { |  | ||||||
| 	if r < utf8.RuneSelf { |  | ||||||
| 		b.WriteByte(byte(r)) |  | ||||||
| 		return 1, nil |  | ||||||
| 	} |  | ||||||
| 	n = utf8.EncodeRune(b.runeBytes[0:], r) |  | ||||||
| 	b.Write(b.runeBytes[0:n]) |  | ||||||
| 	return n, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Read reads the next len(p) bytes from the buffer or until the buffer |  | ||||||
| // is drained.  The return value n is the number of bytes read.  If the |  | ||||||
| // buffer has no data to return, err is io.EOF (unless len(p) is zero); |  | ||||||
| // otherwise it is nil. |  | ||||||
| func (b *Buffer) Read(p []byte) (n int, err error) { |  | ||||||
| 	if b.off >= len(b.buf) { |  | ||||||
| 		// Buffer is empty, reset to recover space. |  | ||||||
| 		b.Truncate(0) |  | ||||||
| 		if len(p) == 0 { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		return 0, io.EOF |  | ||||||
| 	} |  | ||||||
| 	n = copy(p, b.buf[b.off:]) |  | ||||||
| 	b.off += n |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Next returns a slice containing the next n bytes from the buffer, |  | ||||||
| // advancing the buffer as if the bytes had been returned by Read. |  | ||||||
| // If there are fewer than n bytes in the buffer, Next returns the entire buffer. |  | ||||||
| // The slice is only valid until the next call to a read or write method. |  | ||||||
| func (b *Buffer) Next(n int) []byte { |  | ||||||
| 	m := b.Len() |  | ||||||
| 	if n > m { |  | ||||||
| 		n = m |  | ||||||
| 	} |  | ||||||
| 	data := b.buf[b.off : b.off+n] |  | ||||||
| 	b.off += n |  | ||||||
| 	return data |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ReadByte reads and returns the next byte from the buffer. |  | ||||||
| // If no byte is available, it returns error io.EOF. |  | ||||||
| func (b *Buffer) ReadByte() (c byte, err error) { |  | ||||||
| 	if b.off >= len(b.buf) { |  | ||||||
| 		// Buffer is empty, reset to recover space. |  | ||||||
| 		b.Truncate(0) |  | ||||||
| 		return 0, io.EOF |  | ||||||
| 	} |  | ||||||
| 	c = b.buf[b.off] |  | ||||||
| 	b.off++ |  | ||||||
| 	return c, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ReadRune reads and returns the next UTF-8-encoded |  | ||||||
| // Unicode code point from the buffer. |  | ||||||
| // If no bytes are available, the error returned is io.EOF. |  | ||||||
| // If the bytes are an erroneous UTF-8 encoding, it |  | ||||||
| // consumes one byte and returns U+FFFD, 1. |  | ||||||
| func (b *Buffer) ReadRune() (r rune, size int, err error) { |  | ||||||
| 	if b.off >= len(b.buf) { |  | ||||||
| 		// Buffer is empty, reset to recover space. |  | ||||||
| 		b.Truncate(0) |  | ||||||
| 		return 0, 0, io.EOF |  | ||||||
| 	} |  | ||||||
| 	c := b.buf[b.off] |  | ||||||
| 	if c < utf8.RuneSelf { |  | ||||||
| 		b.off++ |  | ||||||
| 		return rune(c), 1, nil |  | ||||||
| 	} |  | ||||||
| 	r, n := utf8.DecodeRune(b.buf[b.off:]) |  | ||||||
| 	b.off += n |  | ||||||
| 	return r, n, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ReadBytes reads until the first occurrence of delim in the input, |  | ||||||
| // returning a slice containing the data up to and including the delimiter. |  | ||||||
| // If ReadBytes encounters an error before finding a delimiter, |  | ||||||
| // it returns the data read before the error and the error itself (often io.EOF). |  | ||||||
| // ReadBytes returns err != nil if and only if the returned data does not end in |  | ||||||
| // delim. |  | ||||||
| func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) { |  | ||||||
| 	slice, err := b.readSlice(delim) |  | ||||||
| 	// return a copy of slice. The buffer's backing array may |  | ||||||
| 	// be overwritten by later calls. |  | ||||||
| 	line = append(line, slice...) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // readSlice is like ReadBytes but returns a reference to internal buffer data. |  | ||||||
| func (b *Buffer) readSlice(delim byte) (line []byte, err error) { |  | ||||||
| 	i := bytes.IndexByte(b.buf[b.off:], delim) |  | ||||||
| 	end := b.off + i + 1 |  | ||||||
| 	if i < 0 { |  | ||||||
| 		end = len(b.buf) |  | ||||||
| 		err = io.EOF |  | ||||||
| 	} |  | ||||||
| 	line = b.buf[b.off:end] |  | ||||||
| 	b.off = end |  | ||||||
| 	return line, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ReadString reads until the first occurrence of delim in the input, |  | ||||||
| // returning a string containing the data up to and including the delimiter. |  | ||||||
| // If ReadString encounters an error before finding a delimiter, |  | ||||||
| // it returns the data read before the error and the error itself (often io.EOF). |  | ||||||
| // ReadString returns err != nil if and only if the returned data does not end |  | ||||||
| // in delim. |  | ||||||
| func (b *Buffer) ReadString(delim byte) (line string, err error) { |  | ||||||
| 	slice, err := b.readSlice(delim) |  | ||||||
| 	return string(slice), err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewBuffer creates and initializes a new Buffer using buf as its initial |  | ||||||
| // contents.  It is intended to prepare a Buffer to read existing data.  It |  | ||||||
| // can also be used to size the internal buffer for writing. To do that, |  | ||||||
| // buf should have the desired capacity but a length of zero. |  | ||||||
| // |  | ||||||
| // In most cases, new(Buffer) (or just declaring a Buffer variable) is |  | ||||||
| // sufficient to initialize a Buffer. |  | ||||||
| func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} } |  | ||||||
|  |  | ||||||
| // NewBufferString creates and initializes a new Buffer using string s as its |  | ||||||
| // initial contents. It is intended to prepare a buffer to read an existing |  | ||||||
| // string. |  | ||||||
| // |  | ||||||
| // In most cases, new(Buffer) (or just declaring a Buffer variable) is |  | ||||||
| // sufficient to initialize a Buffer. |  | ||||||
| func NewBufferString(s string) *Buffer { |  | ||||||
| 	return &Buffer{buf: []byte(s)} |  | ||||||
| } |  | ||||||
							
								
								
									
										11
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer_nopool.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer_nopool.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,11 +0,0 @@ | |||||||
| // +build !go1.3 |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| // Stub version of buffer_pool.go for Go 1.2, which doesn't have sync.Pool. |  | ||||||
|  |  | ||||||
| func Pool(b []byte) {} |  | ||||||
|  |  | ||||||
| func makeSlice(n int) []byte { |  | ||||||
| 	return make([]byte, n) |  | ||||||
| } |  | ||||||
							
								
								
									
										105
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer_pool.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer_pool.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,105 +0,0 @@ | |||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| // +build go1.3 |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| // Allocation pools for Buffers. |  | ||||||
|  |  | ||||||
| import "sync" |  | ||||||
|  |  | ||||||
| var pools [14]sync.Pool |  | ||||||
| var pool64 *sync.Pool |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	var i uint |  | ||||||
| 	// TODO(pquerna): add science here around actual pool sizes. |  | ||||||
| 	for i = 6; i < 20; i++ { |  | ||||||
| 		n := 1 << i |  | ||||||
| 		pools[poolNum(n)].New = func() interface{} { return make([]byte, 0, n) } |  | ||||||
| 	} |  | ||||||
| 	pool64 = &pools[0] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // This returns the pool number that will give a buffer of |  | ||||||
| // at least 'i' bytes. |  | ||||||
| func poolNum(i int) int { |  | ||||||
| 	// TODO(pquerna): convert to log2 w/ bsr asm instruction: |  | ||||||
| 	// 	<https://groups.google.com/forum/#!topic/golang-nuts/uAb5J1_y7ns> |  | ||||||
| 	if i <= 64 { |  | ||||||
| 		return 0 |  | ||||||
| 	} else if i <= 128 { |  | ||||||
| 		return 1 |  | ||||||
| 	} else if i <= 256 { |  | ||||||
| 		return 2 |  | ||||||
| 	} else if i <= 512 { |  | ||||||
| 		return 3 |  | ||||||
| 	} else if i <= 1024 { |  | ||||||
| 		return 4 |  | ||||||
| 	} else if i <= 2048 { |  | ||||||
| 		return 5 |  | ||||||
| 	} else if i <= 4096 { |  | ||||||
| 		return 6 |  | ||||||
| 	} else if i <= 8192 { |  | ||||||
| 		return 7 |  | ||||||
| 	} else if i <= 16384 { |  | ||||||
| 		return 8 |  | ||||||
| 	} else if i <= 32768 { |  | ||||||
| 		return 9 |  | ||||||
| 	} else if i <= 65536 { |  | ||||||
| 		return 10 |  | ||||||
| 	} else if i <= 131072 { |  | ||||||
| 		return 11 |  | ||||||
| 	} else if i <= 262144 { |  | ||||||
| 		return 12 |  | ||||||
| 	} else if i <= 524288 { |  | ||||||
| 		return 13 |  | ||||||
| 	} else { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Send a buffer to the Pool to reuse for other instances. |  | ||||||
| // You may no longer utilize the content of the buffer, since it may be used |  | ||||||
| // by other goroutines. |  | ||||||
| func Pool(b []byte) { |  | ||||||
| 	if b == nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	c := cap(b) |  | ||||||
|  |  | ||||||
| 	// Our smallest buffer is 64 bytes, so we discard smaller buffers. |  | ||||||
| 	if c < 64 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// We need to put the incoming buffer into the NEXT buffer, |  | ||||||
| 	// since a buffer guarantees AT LEAST the number of bytes available |  | ||||||
| 	// that is the top of this buffer. |  | ||||||
| 	// That is the reason for dividing the cap by 2, so it gets into the NEXT bucket. |  | ||||||
| 	// We add 2 to avoid rounding down if size is exactly power of 2. |  | ||||||
| 	pn := poolNum((c + 2) >> 1) |  | ||||||
| 	if pn != -1 { |  | ||||||
| 		pools[pn].Put(b[0:0]) |  | ||||||
| 	} |  | ||||||
| 	// if we didn't have a slot for this []byte, we just drop it and let the GC |  | ||||||
| 	// take care of it. |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // makeSlice allocates a slice of size n -- it will attempt to use a pool'ed |  | ||||||
| // instance whenever possible. |  | ||||||
| func makeSlice(n int) []byte { |  | ||||||
| 	if n <= 64 { |  | ||||||
| 		return pool64.Get().([]byte)[0:n] |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pn := poolNum(n) |  | ||||||
|  |  | ||||||
| 	if pn != -1 { |  | ||||||
| 		return pools[pn].Get().([]byte)[0:n] |  | ||||||
| 	} else { |  | ||||||
| 		return make([]byte, n) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										88
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/bytenum.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/bytenum.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,88 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Portions of this file are on Go stdlib's strconv/iota.go */ |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/pquerna/ffjson/fflib/v1/internal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func ParseFloat(s []byte, bitSize int) (f float64, err error) { |  | ||||||
| 	return internal.ParseFloat(s, bitSize) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ParseUint is like ParseInt but for unsigned numbers, and oeprating on []byte |  | ||||||
| func ParseUint(s []byte, base int, bitSize int) (n uint64, err error) { |  | ||||||
| 	if len(s) == 1 { |  | ||||||
| 		switch s[0] { |  | ||||||
| 		case '0': |  | ||||||
| 			return 0, nil |  | ||||||
| 		case '1': |  | ||||||
| 			return 1, nil |  | ||||||
| 		case '2': |  | ||||||
| 			return 2, nil |  | ||||||
| 		case '3': |  | ||||||
| 			return 3, nil |  | ||||||
| 		case '4': |  | ||||||
| 			return 4, nil |  | ||||||
| 		case '5': |  | ||||||
| 			return 5, nil |  | ||||||
| 		case '6': |  | ||||||
| 			return 6, nil |  | ||||||
| 		case '7': |  | ||||||
| 			return 7, nil |  | ||||||
| 		case '8': |  | ||||||
| 			return 8, nil |  | ||||||
| 		case '9': |  | ||||||
| 			return 9, nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return internal.ParseUint(s, base, bitSize) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func ParseInt(s []byte, base int, bitSize int) (i int64, err error) { |  | ||||||
| 	if len(s) == 1 { |  | ||||||
| 		switch s[0] { |  | ||||||
| 		case '0': |  | ||||||
| 			return 0, nil |  | ||||||
| 		case '1': |  | ||||||
| 			return 1, nil |  | ||||||
| 		case '2': |  | ||||||
| 			return 2, nil |  | ||||||
| 		case '3': |  | ||||||
| 			return 3, nil |  | ||||||
| 		case '4': |  | ||||||
| 			return 4, nil |  | ||||||
| 		case '5': |  | ||||||
| 			return 5, nil |  | ||||||
| 		case '6': |  | ||||||
| 			return 6, nil |  | ||||||
| 		case '7': |  | ||||||
| 			return 7, nil |  | ||||||
| 		case '8': |  | ||||||
| 			return 8, nil |  | ||||||
| 		case '9': |  | ||||||
| 			return 9, nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return internal.ParseInt(s, base, bitSize) |  | ||||||
| } |  | ||||||
							
								
								
									
										378
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/decimal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										378
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/decimal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,378 +0,0 @@ | |||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| // Multiprecision decimal numbers. |  | ||||||
| // For floating-point formatting only; not general purpose. |  | ||||||
| // Only operations are assign and (binary) left/right shift. |  | ||||||
| // Can do binary floating point in multiprecision decimal precisely |  | ||||||
| // because 2 divides 10; cannot do decimal floating point |  | ||||||
| // in multiprecision binary precisely. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| type decimal struct { |  | ||||||
| 	d     [800]byte // digits |  | ||||||
| 	nd    int       // number of digits used |  | ||||||
| 	dp    int       // decimal point |  | ||||||
| 	neg   bool |  | ||||||
| 	trunc bool // discarded nonzero digits beyond d[:nd] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *decimal) String() string { |  | ||||||
| 	n := 10 + a.nd |  | ||||||
| 	if a.dp > 0 { |  | ||||||
| 		n += a.dp |  | ||||||
| 	} |  | ||||||
| 	if a.dp < 0 { |  | ||||||
| 		n += -a.dp |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	buf := make([]byte, n) |  | ||||||
| 	w := 0 |  | ||||||
| 	switch { |  | ||||||
| 	case a.nd == 0: |  | ||||||
| 		return "0" |  | ||||||
|  |  | ||||||
| 	case a.dp <= 0: |  | ||||||
| 		// zeros fill space between decimal point and digits |  | ||||||
| 		buf[w] = '0' |  | ||||||
| 		w++ |  | ||||||
| 		buf[w] = '.' |  | ||||||
| 		w++ |  | ||||||
| 		w += digitZero(buf[w : w+-a.dp]) |  | ||||||
| 		w += copy(buf[w:], a.d[0:a.nd]) |  | ||||||
|  |  | ||||||
| 	case a.dp < a.nd: |  | ||||||
| 		// decimal point in middle of digits |  | ||||||
| 		w += copy(buf[w:], a.d[0:a.dp]) |  | ||||||
| 		buf[w] = '.' |  | ||||||
| 		w++ |  | ||||||
| 		w += copy(buf[w:], a.d[a.dp:a.nd]) |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		// zeros fill space between digits and decimal point |  | ||||||
| 		w += copy(buf[w:], a.d[0:a.nd]) |  | ||||||
| 		w += digitZero(buf[w : w+a.dp-a.nd]) |  | ||||||
| 	} |  | ||||||
| 	return string(buf[0:w]) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func digitZero(dst []byte) int { |  | ||||||
| 	for i := range dst { |  | ||||||
| 		dst[i] = '0' |  | ||||||
| 	} |  | ||||||
| 	return len(dst) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // trim trailing zeros from number. |  | ||||||
| // (They are meaningless; the decimal point is tracked |  | ||||||
| // independent of the number of digits.) |  | ||||||
| func trim(a *decimal) { |  | ||||||
| 	for a.nd > 0 && a.d[a.nd-1] == '0' { |  | ||||||
| 		a.nd-- |  | ||||||
| 	} |  | ||||||
| 	if a.nd == 0 { |  | ||||||
| 		a.dp = 0 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Assign v to a. |  | ||||||
| func (a *decimal) Assign(v uint64) { |  | ||||||
| 	var buf [24]byte |  | ||||||
|  |  | ||||||
| 	// Write reversed decimal in buf. |  | ||||||
| 	n := 0 |  | ||||||
| 	for v > 0 { |  | ||||||
| 		v1 := v / 10 |  | ||||||
| 		v -= 10 * v1 |  | ||||||
| 		buf[n] = byte(v + '0') |  | ||||||
| 		n++ |  | ||||||
| 		v = v1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Reverse again to produce forward decimal in a.d. |  | ||||||
| 	a.nd = 0 |  | ||||||
| 	for n--; n >= 0; n-- { |  | ||||||
| 		a.d[a.nd] = buf[n] |  | ||||||
| 		a.nd++ |  | ||||||
| 	} |  | ||||||
| 	a.dp = a.nd |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Maximum shift that we can do in one pass without overflow. |  | ||||||
| // Signed int has 31 bits, and we have to be able to accommodate 9<<k. |  | ||||||
| const maxShift = 27 |  | ||||||
|  |  | ||||||
| // Binary shift right (* 2) by k bits.  k <= maxShift to avoid overflow. |  | ||||||
| func rightShift(a *decimal, k uint) { |  | ||||||
| 	r := 0 // read pointer |  | ||||||
| 	w := 0 // write pointer |  | ||||||
|  |  | ||||||
| 	// Pick up enough leading digits to cover first shift. |  | ||||||
| 	n := 0 |  | ||||||
| 	for ; n>>k == 0; r++ { |  | ||||||
| 		if r >= a.nd { |  | ||||||
| 			if n == 0 { |  | ||||||
| 				// a == 0; shouldn't get here, but handle anyway. |  | ||||||
| 				a.nd = 0 |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			for n>>k == 0 { |  | ||||||
| 				n = n * 10 |  | ||||||
| 				r++ |  | ||||||
| 			} |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		c := int(a.d[r]) |  | ||||||
| 		n = n*10 + c - '0' |  | ||||||
| 	} |  | ||||||
| 	a.dp -= r - 1 |  | ||||||
|  |  | ||||||
| 	// Pick up a digit, put down a digit. |  | ||||||
| 	for ; r < a.nd; r++ { |  | ||||||
| 		c := int(a.d[r]) |  | ||||||
| 		dig := n >> k |  | ||||||
| 		n -= dig << k |  | ||||||
| 		a.d[w] = byte(dig + '0') |  | ||||||
| 		w++ |  | ||||||
| 		n = n*10 + c - '0' |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Put down extra digits. |  | ||||||
| 	for n > 0 { |  | ||||||
| 		dig := n >> k |  | ||||||
| 		n -= dig << k |  | ||||||
| 		if w < len(a.d) { |  | ||||||
| 			a.d[w] = byte(dig + '0') |  | ||||||
| 			w++ |  | ||||||
| 		} else if dig > 0 { |  | ||||||
| 			a.trunc = true |  | ||||||
| 		} |  | ||||||
| 		n = n * 10 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	a.nd = w |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Cheat sheet for left shift: table indexed by shift count giving |  | ||||||
| // number of new digits that will be introduced by that shift. |  | ||||||
| // |  | ||||||
| // For example, leftcheats[4] = {2, "625"}.  That means that |  | ||||||
| // if we are shifting by 4 (multiplying by 16), it will add 2 digits |  | ||||||
| // when the string prefix is "625" through "999", and one fewer digit |  | ||||||
| // if the string prefix is "000" through "624". |  | ||||||
| // |  | ||||||
| // Credit for this trick goes to Ken. |  | ||||||
|  |  | ||||||
| type leftCheat struct { |  | ||||||
| 	delta  int    // number of new digits |  | ||||||
| 	cutoff string //   minus one digit if original < a. |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var leftcheats = []leftCheat{ |  | ||||||
| 	// Leading digits of 1/2^i = 5^i. |  | ||||||
| 	// 5^23 is not an exact 64-bit floating point number, |  | ||||||
| 	// so have to use bc for the math. |  | ||||||
| 	/* |  | ||||||
| 		seq 27 | sed 's/^/5^/' | bc | |  | ||||||
| 		awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," } |  | ||||||
| 		{ |  | ||||||
| 			log2 = log(2)/log(10) |  | ||||||
| 			printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n", |  | ||||||
| 				int(log2*NR+1), $0, 2**NR) |  | ||||||
| 		}' |  | ||||||
| 	*/ |  | ||||||
| 	{0, ""}, |  | ||||||
| 	{1, "5"},                   // * 2 |  | ||||||
| 	{1, "25"},                  // * 4 |  | ||||||
| 	{1, "125"},                 // * 8 |  | ||||||
| 	{2, "625"},                 // * 16 |  | ||||||
| 	{2, "3125"},                // * 32 |  | ||||||
| 	{2, "15625"},               // * 64 |  | ||||||
| 	{3, "78125"},               // * 128 |  | ||||||
| 	{3, "390625"},              // * 256 |  | ||||||
| 	{3, "1953125"},             // * 512 |  | ||||||
| 	{4, "9765625"},             // * 1024 |  | ||||||
| 	{4, "48828125"},            // * 2048 |  | ||||||
| 	{4, "244140625"},           // * 4096 |  | ||||||
| 	{4, "1220703125"},          // * 8192 |  | ||||||
| 	{5, "6103515625"},          // * 16384 |  | ||||||
| 	{5, "30517578125"},         // * 32768 |  | ||||||
| 	{5, "152587890625"},        // * 65536 |  | ||||||
| 	{6, "762939453125"},        // * 131072 |  | ||||||
| 	{6, "3814697265625"},       // * 262144 |  | ||||||
| 	{6, "19073486328125"},      // * 524288 |  | ||||||
| 	{7, "95367431640625"},      // * 1048576 |  | ||||||
| 	{7, "476837158203125"},     // * 2097152 |  | ||||||
| 	{7, "2384185791015625"},    // * 4194304 |  | ||||||
| 	{7, "11920928955078125"},   // * 8388608 |  | ||||||
| 	{8, "59604644775390625"},   // * 16777216 |  | ||||||
| 	{8, "298023223876953125"},  // * 33554432 |  | ||||||
| 	{8, "1490116119384765625"}, // * 67108864 |  | ||||||
| 	{9, "7450580596923828125"}, // * 134217728 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Is the leading prefix of b lexicographically less than s? |  | ||||||
| func prefixIsLessThan(b []byte, s string) bool { |  | ||||||
| 	for i := 0; i < len(s); i++ { |  | ||||||
| 		if i >= len(b) { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		if b[i] != s[i] { |  | ||||||
| 			return b[i] < s[i] |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Binary shift left (/ 2) by k bits.  k <= maxShift to avoid overflow. |  | ||||||
| func leftShift(a *decimal, k uint) { |  | ||||||
| 	delta := leftcheats[k].delta |  | ||||||
| 	if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) { |  | ||||||
| 		delta-- |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	r := a.nd         // read index |  | ||||||
| 	w := a.nd + delta // write index |  | ||||||
| 	n := 0 |  | ||||||
|  |  | ||||||
| 	// Pick up a digit, put down a digit. |  | ||||||
| 	for r--; r >= 0; r-- { |  | ||||||
| 		n += (int(a.d[r]) - '0') << k |  | ||||||
| 		quo := n / 10 |  | ||||||
| 		rem := n - 10*quo |  | ||||||
| 		w-- |  | ||||||
| 		if w < len(a.d) { |  | ||||||
| 			a.d[w] = byte(rem + '0') |  | ||||||
| 		} else if rem != 0 { |  | ||||||
| 			a.trunc = true |  | ||||||
| 		} |  | ||||||
| 		n = quo |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Put down extra digits. |  | ||||||
| 	for n > 0 { |  | ||||||
| 		quo := n / 10 |  | ||||||
| 		rem := n - 10*quo |  | ||||||
| 		w-- |  | ||||||
| 		if w < len(a.d) { |  | ||||||
| 			a.d[w] = byte(rem + '0') |  | ||||||
| 		} else if rem != 0 { |  | ||||||
| 			a.trunc = true |  | ||||||
| 		} |  | ||||||
| 		n = quo |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	a.nd += delta |  | ||||||
| 	if a.nd >= len(a.d) { |  | ||||||
| 		a.nd = len(a.d) |  | ||||||
| 	} |  | ||||||
| 	a.dp += delta |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Binary shift left (k > 0) or right (k < 0). |  | ||||||
| func (a *decimal) Shift(k int) { |  | ||||||
| 	switch { |  | ||||||
| 	case a.nd == 0: |  | ||||||
| 		// nothing to do: a == 0 |  | ||||||
| 	case k > 0: |  | ||||||
| 		for k > maxShift { |  | ||||||
| 			leftShift(a, maxShift) |  | ||||||
| 			k -= maxShift |  | ||||||
| 		} |  | ||||||
| 		leftShift(a, uint(k)) |  | ||||||
| 	case k < 0: |  | ||||||
| 		for k < -maxShift { |  | ||||||
| 			rightShift(a, maxShift) |  | ||||||
| 			k += maxShift |  | ||||||
| 		} |  | ||||||
| 		rightShift(a, uint(-k)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // If we chop a at nd digits, should we round up? |  | ||||||
| func shouldRoundUp(a *decimal, nd int) bool { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even |  | ||||||
| 		// if we truncated, a little higher than what's recorded - always round up |  | ||||||
| 		if a.trunc { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		return nd > 0 && (a.d[nd-1]-'0')%2 != 0 |  | ||||||
| 	} |  | ||||||
| 	// not halfway - digit tells all |  | ||||||
| 	return a.d[nd] >= '5' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round a to nd digits (or fewer). |  | ||||||
| // If nd is zero, it means we're rounding |  | ||||||
| // just to the left of the digits, as in |  | ||||||
| // 0.09 -> 0.1. |  | ||||||
| func (a *decimal) Round(nd int) { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if shouldRoundUp(a, nd) { |  | ||||||
| 		a.RoundUp(nd) |  | ||||||
| 	} else { |  | ||||||
| 		a.RoundDown(nd) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round a down to nd digits (or fewer). |  | ||||||
| func (a *decimal) RoundDown(nd int) { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	a.nd = nd |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round a up to nd digits (or fewer). |  | ||||||
| func (a *decimal) RoundUp(nd int) { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// round up |  | ||||||
| 	for i := nd - 1; i >= 0; i-- { |  | ||||||
| 		c := a.d[i] |  | ||||||
| 		if c < '9' { // can stop after this digit |  | ||||||
| 			a.d[i]++ |  | ||||||
| 			a.nd = i + 1 |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Number is all 9s. |  | ||||||
| 	// Change to single 1 with adjusted decimal point. |  | ||||||
| 	a.d[0] = '1' |  | ||||||
| 	a.nd = 1 |  | ||||||
| 	a.dp++ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Extract integer part, rounded appropriately. |  | ||||||
| // No guarantees about overflow. |  | ||||||
| func (a *decimal) RoundedInteger() uint64 { |  | ||||||
| 	if a.dp > 20 { |  | ||||||
| 		return 0xFFFFFFFFFFFFFFFF |  | ||||||
| 	} |  | ||||||
| 	var i int |  | ||||||
| 	n := uint64(0) |  | ||||||
| 	for i = 0; i < a.dp && i < a.nd; i++ { |  | ||||||
| 		n = n*10 + uint64(a.d[i]-'0') |  | ||||||
| 	} |  | ||||||
| 	for ; i < a.dp; i++ { |  | ||||||
| 		n *= 10 |  | ||||||
| 	} |  | ||||||
| 	if shouldRoundUp(a, a.dp) { |  | ||||||
| 		n++ |  | ||||||
| 	} |  | ||||||
| 	return n |  | ||||||
| } |  | ||||||
							
								
								
									
										668
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/extfloat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										668
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/extfloat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,668 +0,0 @@ | |||||||
| // Copyright 2011 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| // An extFloat represents an extended floating-point number, with more |  | ||||||
| // precision than a float64. It does not try to save bits: the |  | ||||||
| // number represented by the structure is mant*(2^exp), with a negative |  | ||||||
| // sign if neg is true. |  | ||||||
| type extFloat struct { |  | ||||||
| 	mant uint64 |  | ||||||
| 	exp  int |  | ||||||
| 	neg  bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Powers of ten taken from double-conversion library. |  | ||||||
| // http://code.google.com/p/double-conversion/ |  | ||||||
| const ( |  | ||||||
| 	firstPowerOfTen = -348 |  | ||||||
| 	stepPowerOfTen  = 8 |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var smallPowersOfTen = [...]extFloat{ |  | ||||||
| 	{1 << 63, -63, false},        // 1 |  | ||||||
| 	{0xa << 60, -60, false},      // 1e1 |  | ||||||
| 	{0x64 << 57, -57, false},     // 1e2 |  | ||||||
| 	{0x3e8 << 54, -54, false},    // 1e3 |  | ||||||
| 	{0x2710 << 50, -50, false},   // 1e4 |  | ||||||
| 	{0x186a0 << 47, -47, false},  // 1e5 |  | ||||||
| 	{0xf4240 << 44, -44, false},  // 1e6 |  | ||||||
| 	{0x989680 << 40, -40, false}, // 1e7 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var powersOfTen = [...]extFloat{ |  | ||||||
| 	{0xfa8fd5a0081c0288, -1220, false}, // 10^-348 |  | ||||||
| 	{0xbaaee17fa23ebf76, -1193, false}, // 10^-340 |  | ||||||
| 	{0x8b16fb203055ac76, -1166, false}, // 10^-332 |  | ||||||
| 	{0xcf42894a5dce35ea, -1140, false}, // 10^-324 |  | ||||||
| 	{0x9a6bb0aa55653b2d, -1113, false}, // 10^-316 |  | ||||||
| 	{0xe61acf033d1a45df, -1087, false}, // 10^-308 |  | ||||||
| 	{0xab70fe17c79ac6ca, -1060, false}, // 10^-300 |  | ||||||
| 	{0xff77b1fcbebcdc4f, -1034, false}, // 10^-292 |  | ||||||
| 	{0xbe5691ef416bd60c, -1007, false}, // 10^-284 |  | ||||||
| 	{0x8dd01fad907ffc3c, -980, false},  // 10^-276 |  | ||||||
| 	{0xd3515c2831559a83, -954, false},  // 10^-268 |  | ||||||
| 	{0x9d71ac8fada6c9b5, -927, false},  // 10^-260 |  | ||||||
| 	{0xea9c227723ee8bcb, -901, false},  // 10^-252 |  | ||||||
| 	{0xaecc49914078536d, -874, false},  // 10^-244 |  | ||||||
| 	{0x823c12795db6ce57, -847, false},  // 10^-236 |  | ||||||
| 	{0xc21094364dfb5637, -821, false},  // 10^-228 |  | ||||||
| 	{0x9096ea6f3848984f, -794, false},  // 10^-220 |  | ||||||
| 	{0xd77485cb25823ac7, -768, false},  // 10^-212 |  | ||||||
| 	{0xa086cfcd97bf97f4, -741, false},  // 10^-204 |  | ||||||
| 	{0xef340a98172aace5, -715, false},  // 10^-196 |  | ||||||
| 	{0xb23867fb2a35b28e, -688, false},  // 10^-188 |  | ||||||
| 	{0x84c8d4dfd2c63f3b, -661, false},  // 10^-180 |  | ||||||
| 	{0xc5dd44271ad3cdba, -635, false},  // 10^-172 |  | ||||||
| 	{0x936b9fcebb25c996, -608, false},  // 10^-164 |  | ||||||
| 	{0xdbac6c247d62a584, -582, false},  // 10^-156 |  | ||||||
| 	{0xa3ab66580d5fdaf6, -555, false},  // 10^-148 |  | ||||||
| 	{0xf3e2f893dec3f126, -529, false},  // 10^-140 |  | ||||||
| 	{0xb5b5ada8aaff80b8, -502, false},  // 10^-132 |  | ||||||
| 	{0x87625f056c7c4a8b, -475, false},  // 10^-124 |  | ||||||
| 	{0xc9bcff6034c13053, -449, false},  // 10^-116 |  | ||||||
| 	{0x964e858c91ba2655, -422, false},  // 10^-108 |  | ||||||
| 	{0xdff9772470297ebd, -396, false},  // 10^-100 |  | ||||||
| 	{0xa6dfbd9fb8e5b88f, -369, false},  // 10^-92 |  | ||||||
| 	{0xf8a95fcf88747d94, -343, false},  // 10^-84 |  | ||||||
| 	{0xb94470938fa89bcf, -316, false},  // 10^-76 |  | ||||||
| 	{0x8a08f0f8bf0f156b, -289, false},  // 10^-68 |  | ||||||
| 	{0xcdb02555653131b6, -263, false},  // 10^-60 |  | ||||||
| 	{0x993fe2c6d07b7fac, -236, false},  // 10^-52 |  | ||||||
| 	{0xe45c10c42a2b3b06, -210, false},  // 10^-44 |  | ||||||
| 	{0xaa242499697392d3, -183, false},  // 10^-36 |  | ||||||
| 	{0xfd87b5f28300ca0e, -157, false},  // 10^-28 |  | ||||||
| 	{0xbce5086492111aeb, -130, false},  // 10^-20 |  | ||||||
| 	{0x8cbccc096f5088cc, -103, false},  // 10^-12 |  | ||||||
| 	{0xd1b71758e219652c, -77, false},   // 10^-4 |  | ||||||
| 	{0x9c40000000000000, -50, false},   // 10^4 |  | ||||||
| 	{0xe8d4a51000000000, -24, false},   // 10^12 |  | ||||||
| 	{0xad78ebc5ac620000, 3, false},     // 10^20 |  | ||||||
| 	{0x813f3978f8940984, 30, false},    // 10^28 |  | ||||||
| 	{0xc097ce7bc90715b3, 56, false},    // 10^36 |  | ||||||
| 	{0x8f7e32ce7bea5c70, 83, false},    // 10^44 |  | ||||||
| 	{0xd5d238a4abe98068, 109, false},   // 10^52 |  | ||||||
| 	{0x9f4f2726179a2245, 136, false},   // 10^60 |  | ||||||
| 	{0xed63a231d4c4fb27, 162, false},   // 10^68 |  | ||||||
| 	{0xb0de65388cc8ada8, 189, false},   // 10^76 |  | ||||||
| 	{0x83c7088e1aab65db, 216, false},   // 10^84 |  | ||||||
| 	{0xc45d1df942711d9a, 242, false},   // 10^92 |  | ||||||
| 	{0x924d692ca61be758, 269, false},   // 10^100 |  | ||||||
| 	{0xda01ee641a708dea, 295, false},   // 10^108 |  | ||||||
| 	{0xa26da3999aef774a, 322, false},   // 10^116 |  | ||||||
| 	{0xf209787bb47d6b85, 348, false},   // 10^124 |  | ||||||
| 	{0xb454e4a179dd1877, 375, false},   // 10^132 |  | ||||||
| 	{0x865b86925b9bc5c2, 402, false},   // 10^140 |  | ||||||
| 	{0xc83553c5c8965d3d, 428, false},   // 10^148 |  | ||||||
| 	{0x952ab45cfa97a0b3, 455, false},   // 10^156 |  | ||||||
| 	{0xde469fbd99a05fe3, 481, false},   // 10^164 |  | ||||||
| 	{0xa59bc234db398c25, 508, false},   // 10^172 |  | ||||||
| 	{0xf6c69a72a3989f5c, 534, false},   // 10^180 |  | ||||||
| 	{0xb7dcbf5354e9bece, 561, false},   // 10^188 |  | ||||||
| 	{0x88fcf317f22241e2, 588, false},   // 10^196 |  | ||||||
| 	{0xcc20ce9bd35c78a5, 614, false},   // 10^204 |  | ||||||
| 	{0x98165af37b2153df, 641, false},   // 10^212 |  | ||||||
| 	{0xe2a0b5dc971f303a, 667, false},   // 10^220 |  | ||||||
| 	{0xa8d9d1535ce3b396, 694, false},   // 10^228 |  | ||||||
| 	{0xfb9b7cd9a4a7443c, 720, false},   // 10^236 |  | ||||||
| 	{0xbb764c4ca7a44410, 747, false},   // 10^244 |  | ||||||
| 	{0x8bab8eefb6409c1a, 774, false},   // 10^252 |  | ||||||
| 	{0xd01fef10a657842c, 800, false},   // 10^260 |  | ||||||
| 	{0x9b10a4e5e9913129, 827, false},   // 10^268 |  | ||||||
| 	{0xe7109bfba19c0c9d, 853, false},   // 10^276 |  | ||||||
| 	{0xac2820d9623bf429, 880, false},   // 10^284 |  | ||||||
| 	{0x80444b5e7aa7cf85, 907, false},   // 10^292 |  | ||||||
| 	{0xbf21e44003acdd2d, 933, false},   // 10^300 |  | ||||||
| 	{0x8e679c2f5e44ff8f, 960, false},   // 10^308 |  | ||||||
| 	{0xd433179d9c8cb841, 986, false},   // 10^316 |  | ||||||
| 	{0x9e19db92b4e31ba9, 1013, false},  // 10^324 |  | ||||||
| 	{0xeb96bf6ebadf77d9, 1039, false},  // 10^332 |  | ||||||
| 	{0xaf87023b9bf0ee6b, 1066, false},  // 10^340 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // floatBits returns the bits of the float64 that best approximates |  | ||||||
| // the extFloat passed as receiver. Overflow is set to true if |  | ||||||
| // the resulting float64 is ±Inf. |  | ||||||
| func (f *extFloat) floatBits(flt *floatInfo) (bits uint64, overflow bool) { |  | ||||||
| 	f.Normalize() |  | ||||||
|  |  | ||||||
| 	exp := f.exp + 63 |  | ||||||
|  |  | ||||||
| 	// Exponent too small. |  | ||||||
| 	if exp < flt.bias+1 { |  | ||||||
| 		n := flt.bias + 1 - exp |  | ||||||
| 		f.mant >>= uint(n) |  | ||||||
| 		exp += n |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Extract 1+flt.mantbits bits from the 64-bit mantissa. |  | ||||||
| 	mant := f.mant >> (63 - flt.mantbits) |  | ||||||
| 	if f.mant&(1<<(62-flt.mantbits)) != 0 { |  | ||||||
| 		// Round up. |  | ||||||
| 		mant += 1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Rounding might have added a bit; shift down. |  | ||||||
| 	if mant == 2<<flt.mantbits { |  | ||||||
| 		mant >>= 1 |  | ||||||
| 		exp++ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Infinities. |  | ||||||
| 	if exp-flt.bias >= 1<<flt.expbits-1 { |  | ||||||
| 		// ±Inf |  | ||||||
| 		mant = 0 |  | ||||||
| 		exp = 1<<flt.expbits - 1 + flt.bias |  | ||||||
| 		overflow = true |  | ||||||
| 	} else if mant&(1<<flt.mantbits) == 0 { |  | ||||||
| 		// Denormalized? |  | ||||||
| 		exp = flt.bias |  | ||||||
| 	} |  | ||||||
| 	// Assemble bits. |  | ||||||
| 	bits = mant & (uint64(1)<<flt.mantbits - 1) |  | ||||||
| 	bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits |  | ||||||
| 	if f.neg { |  | ||||||
| 		bits |= 1 << (flt.mantbits + flt.expbits) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AssignComputeBounds sets f to the floating point value |  | ||||||
| // defined by mant, exp and precision given by flt. It returns |  | ||||||
| // lower, upper such that any number in the closed interval |  | ||||||
| // [lower, upper] is converted back to the same floating point number. |  | ||||||
| func (f *extFloat) AssignComputeBounds(mant uint64, exp int, neg bool, flt *floatInfo) (lower, upper extFloat) { |  | ||||||
| 	f.mant = mant |  | ||||||
| 	f.exp = exp - int(flt.mantbits) |  | ||||||
| 	f.neg = neg |  | ||||||
| 	if f.exp <= 0 && mant == (mant>>uint(-f.exp))<<uint(-f.exp) { |  | ||||||
| 		// An exact integer |  | ||||||
| 		f.mant >>= uint(-f.exp) |  | ||||||
| 		f.exp = 0 |  | ||||||
| 		return *f, *f |  | ||||||
| 	} |  | ||||||
| 	expBiased := exp - flt.bias |  | ||||||
|  |  | ||||||
| 	upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg} |  | ||||||
| 	if mant != 1<<flt.mantbits || expBiased == 1 { |  | ||||||
| 		lower = extFloat{mant: 2*f.mant - 1, exp: f.exp - 1, neg: f.neg} |  | ||||||
| 	} else { |  | ||||||
| 		lower = extFloat{mant: 4*f.mant - 1, exp: f.exp - 2, neg: f.neg} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Normalize normalizes f so that the highest bit of the mantissa is |  | ||||||
| // set, and returns the number by which the mantissa was left-shifted. |  | ||||||
| func (f *extFloat) Normalize() (shift uint) { |  | ||||||
| 	mant, exp := f.mant, f.exp |  | ||||||
| 	if mant == 0 { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-32) == 0 { |  | ||||||
| 		mant <<= 32 |  | ||||||
| 		exp -= 32 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-16) == 0 { |  | ||||||
| 		mant <<= 16 |  | ||||||
| 		exp -= 16 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-8) == 0 { |  | ||||||
| 		mant <<= 8 |  | ||||||
| 		exp -= 8 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-4) == 0 { |  | ||||||
| 		mant <<= 4 |  | ||||||
| 		exp -= 4 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-2) == 0 { |  | ||||||
| 		mant <<= 2 |  | ||||||
| 		exp -= 2 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-1) == 0 { |  | ||||||
| 		mant <<= 1 |  | ||||||
| 		exp -= 1 |  | ||||||
| 	} |  | ||||||
| 	shift = uint(f.exp - exp) |  | ||||||
| 	f.mant, f.exp = mant, exp |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Multiply sets f to the product f*g: the result is correctly rounded, |  | ||||||
| // but not normalized. |  | ||||||
| func (f *extFloat) Multiply(g extFloat) { |  | ||||||
| 	fhi, flo := f.mant>>32, uint64(uint32(f.mant)) |  | ||||||
| 	ghi, glo := g.mant>>32, uint64(uint32(g.mant)) |  | ||||||
|  |  | ||||||
| 	// Cross products. |  | ||||||
| 	cross1 := fhi * glo |  | ||||||
| 	cross2 := flo * ghi |  | ||||||
|  |  | ||||||
| 	// f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo |  | ||||||
| 	f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32) |  | ||||||
| 	rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32) |  | ||||||
| 	// Round up. |  | ||||||
| 	rem += (1 << 31) |  | ||||||
|  |  | ||||||
| 	f.mant += (rem >> 32) |  | ||||||
| 	f.exp = f.exp + g.exp + 64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var uint64pow10 = [...]uint64{ |  | ||||||
| 	1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, |  | ||||||
| 	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AssignDecimal sets f to an approximate value mantissa*10^exp. It |  | ||||||
| // returns true if the value represented by f is guaranteed to be the |  | ||||||
| // best approximation of d after being rounded to a float64 or |  | ||||||
| // float32 depending on flt. |  | ||||||
| func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) { |  | ||||||
| 	const uint64digits = 19 |  | ||||||
| 	const errorscale = 8 |  | ||||||
| 	errors := 0 // An upper bound for error, computed in errorscale*ulp. |  | ||||||
| 	if trunc { |  | ||||||
| 		// the decimal number was truncated. |  | ||||||
| 		errors += errorscale / 2 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	f.mant = mantissa |  | ||||||
| 	f.exp = 0 |  | ||||||
| 	f.neg = neg |  | ||||||
|  |  | ||||||
| 	// Multiply by powers of ten. |  | ||||||
| 	i := (exp10 - firstPowerOfTen) / stepPowerOfTen |  | ||||||
| 	if exp10 < firstPowerOfTen || i >= len(powersOfTen) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen |  | ||||||
|  |  | ||||||
| 	// We multiply by exp%step |  | ||||||
| 	if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] { |  | ||||||
| 		// We can multiply the mantissa exactly. |  | ||||||
| 		f.mant *= uint64pow10[adjExp] |  | ||||||
| 		f.Normalize() |  | ||||||
| 	} else { |  | ||||||
| 		f.Normalize() |  | ||||||
| 		f.Multiply(smallPowersOfTen[adjExp]) |  | ||||||
| 		errors += errorscale / 2 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// We multiply by 10 to the exp - exp%step. |  | ||||||
| 	f.Multiply(powersOfTen[i]) |  | ||||||
| 	if errors > 0 { |  | ||||||
| 		errors += 1 |  | ||||||
| 	} |  | ||||||
| 	errors += errorscale / 2 |  | ||||||
|  |  | ||||||
| 	// Normalize |  | ||||||
| 	shift := f.Normalize() |  | ||||||
| 	errors <<= shift |  | ||||||
|  |  | ||||||
| 	// Now f is a good approximation of the decimal. |  | ||||||
| 	// Check whether the error is too large: that is, if the mantissa |  | ||||||
| 	// is perturbated by the error, the resulting float64 will change. |  | ||||||
| 	// The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits. |  | ||||||
| 	// |  | ||||||
| 	// In many cases the approximation will be good enough. |  | ||||||
| 	denormalExp := flt.bias - 63 |  | ||||||
| 	var extrabits uint |  | ||||||
| 	if f.exp <= denormalExp { |  | ||||||
| 		// f.mant * 2^f.exp is smaller than 2^(flt.bias+1). |  | ||||||
| 		extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp)) |  | ||||||
| 	} else { |  | ||||||
| 		extrabits = uint(63 - flt.mantbits) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	halfway := uint64(1) << (extrabits - 1) |  | ||||||
| 	mant_extra := f.mant & (1<<extrabits - 1) |  | ||||||
|  |  | ||||||
| 	// Do a signed comparison here! If the error estimate could make |  | ||||||
| 	// the mantissa round differently for the conversion to double, |  | ||||||
| 	// then we can't give a definite answer. |  | ||||||
| 	if int64(halfway)-int64(errors) < int64(mant_extra) && |  | ||||||
| 		int64(mant_extra) < int64(halfway)+int64(errors) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Frexp10 is an analogue of math.Frexp for decimal powers. It scales |  | ||||||
| // f by an approximate power of ten 10^-exp, and returns exp10, so |  | ||||||
| // that f*10^exp10 has the same value as the old f, up to an ulp, |  | ||||||
| // as well as the index of 10^-exp in the powersOfTen table. |  | ||||||
| func (f *extFloat) frexp10() (exp10, index int) { |  | ||||||
| 	// The constants expMin and expMax constrain the final value of the |  | ||||||
| 	// binary exponent of f. We want a small integral part in the result |  | ||||||
| 	// because finding digits of an integer requires divisions, whereas |  | ||||||
| 	// digits of the fractional part can be found by repeatedly multiplying |  | ||||||
| 	// by 10. |  | ||||||
| 	const expMin = -60 |  | ||||||
| 	const expMax = -32 |  | ||||||
| 	// Find power of ten such that x * 10^n has a binary exponent |  | ||||||
| 	// between expMin and expMax. |  | ||||||
| 	approxExp10 := ((expMin+expMax)/2 - f.exp) * 28 / 93 // log(10)/log(2) is close to 93/28. |  | ||||||
| 	i := (approxExp10 - firstPowerOfTen) / stepPowerOfTen |  | ||||||
| Loop: |  | ||||||
| 	for { |  | ||||||
| 		exp := f.exp + powersOfTen[i].exp + 64 |  | ||||||
| 		switch { |  | ||||||
| 		case exp < expMin: |  | ||||||
| 			i++ |  | ||||||
| 		case exp > expMax: |  | ||||||
| 			i-- |  | ||||||
| 		default: |  | ||||||
| 			break Loop |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	// Apply the desired decimal shift on f. It will have exponent |  | ||||||
| 	// in the desired range. This is multiplication by 10^-exp10. |  | ||||||
| 	f.Multiply(powersOfTen[i]) |  | ||||||
|  |  | ||||||
| 	return -(firstPowerOfTen + i*stepPowerOfTen), i |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // frexp10Many applies a common shift by a power of ten to a, b, c. |  | ||||||
| func frexp10Many(a, b, c *extFloat) (exp10 int) { |  | ||||||
| 	exp10, i := c.frexp10() |  | ||||||
| 	a.Multiply(powersOfTen[i]) |  | ||||||
| 	b.Multiply(powersOfTen[i]) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // FixedDecimal stores in d the first n significant digits |  | ||||||
| // of the decimal representation of f. It returns false |  | ||||||
| // if it cannot be sure of the answer. |  | ||||||
| func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool { |  | ||||||
| 	if f.mant == 0 { |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		d.dp = 0 |  | ||||||
| 		d.neg = f.neg |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if n == 0 { |  | ||||||
| 		panic("strconv: internal error: extFloat.FixedDecimal called with n == 0") |  | ||||||
| 	} |  | ||||||
| 	// Multiply by an appropriate power of ten to have a reasonable |  | ||||||
| 	// number to process. |  | ||||||
| 	f.Normalize() |  | ||||||
| 	exp10, _ := f.frexp10() |  | ||||||
|  |  | ||||||
| 	shift := uint(-f.exp) |  | ||||||
| 	integer := uint32(f.mant >> shift) |  | ||||||
| 	fraction := f.mant - (uint64(integer) << shift) |  | ||||||
| 	ε := uint64(1) // ε is the uncertainty we have on the mantissa of f. |  | ||||||
|  |  | ||||||
| 	// Write exactly n digits to d. |  | ||||||
| 	needed := n        // how many digits are left to write. |  | ||||||
| 	integerDigits := 0 // the number of decimal digits of integer. |  | ||||||
| 	pow10 := uint64(1) // the power of ten by which f was scaled. |  | ||||||
| 	for i, pow := 0, uint64(1); i < 20; i++ { |  | ||||||
| 		if pow > uint64(integer) { |  | ||||||
| 			integerDigits = i |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		pow *= 10 |  | ||||||
| 	} |  | ||||||
| 	rest := integer |  | ||||||
| 	if integerDigits > needed { |  | ||||||
| 		// the integral part is already large, trim the last digits. |  | ||||||
| 		pow10 = uint64pow10[integerDigits-needed] |  | ||||||
| 		integer /= uint32(pow10) |  | ||||||
| 		rest -= integer * uint32(pow10) |  | ||||||
| 	} else { |  | ||||||
| 		rest = 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Write the digits of integer: the digits of rest are omitted. |  | ||||||
| 	var buf [32]byte |  | ||||||
| 	pos := len(buf) |  | ||||||
| 	for v := integer; v > 0; { |  | ||||||
| 		v1 := v / 10 |  | ||||||
| 		v -= 10 * v1 |  | ||||||
| 		pos-- |  | ||||||
| 		buf[pos] = byte(v + '0') |  | ||||||
| 		v = v1 |  | ||||||
| 	} |  | ||||||
| 	for i := pos; i < len(buf); i++ { |  | ||||||
| 		d.d[i-pos] = buf[i] |  | ||||||
| 	} |  | ||||||
| 	nd := len(buf) - pos |  | ||||||
| 	d.nd = nd |  | ||||||
| 	d.dp = integerDigits + exp10 |  | ||||||
| 	needed -= nd |  | ||||||
|  |  | ||||||
| 	if needed > 0 { |  | ||||||
| 		if rest != 0 || pow10 != 1 { |  | ||||||
| 			panic("strconv: internal error, rest != 0 but needed > 0") |  | ||||||
| 		} |  | ||||||
| 		// Emit digits for the fractional part. Each time, 10*fraction |  | ||||||
| 		// fits in a uint64 without overflow. |  | ||||||
| 		for needed > 0 { |  | ||||||
| 			fraction *= 10 |  | ||||||
| 			ε *= 10 // the uncertainty scales as we multiply by ten. |  | ||||||
| 			if 2*ε > 1<<shift { |  | ||||||
| 				// the error is so large it could modify which digit to write, abort. |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 			digit := fraction >> shift |  | ||||||
| 			d.d[nd] = byte(digit + '0') |  | ||||||
| 			fraction -= digit << shift |  | ||||||
| 			nd++ |  | ||||||
| 			needed-- |  | ||||||
| 		} |  | ||||||
| 		d.nd = nd |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// We have written a truncation of f (a numerator / 10^d.dp). The remaining part |  | ||||||
| 	// can be interpreted as a small number (< 1) to be added to the last digit of the |  | ||||||
| 	// numerator. |  | ||||||
| 	// |  | ||||||
| 	// If rest > 0, the amount is: |  | ||||||
| 	//    (rest<<shift | fraction) / (pow10 << shift) |  | ||||||
| 	//    fraction being known with a ±ε uncertainty. |  | ||||||
| 	//    The fact that n > 0 guarantees that pow10 << shift does not overflow a uint64. |  | ||||||
| 	// |  | ||||||
| 	// If rest = 0, pow10 == 1 and the amount is |  | ||||||
| 	//    fraction / (1 << shift) |  | ||||||
| 	//    fraction being known with a ±ε uncertainty. |  | ||||||
| 	// |  | ||||||
| 	// We pass this information to the rounding routine for adjustment. |  | ||||||
|  |  | ||||||
| 	ok := adjustLastDigitFixed(d, uint64(rest)<<shift|fraction, pow10, shift, ε) |  | ||||||
| 	if !ok { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	// Trim trailing zeros. |  | ||||||
| 	for i := d.nd - 1; i >= 0; i-- { |  | ||||||
| 		if d.d[i] != '0' { |  | ||||||
| 			d.nd = i + 1 |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // adjustLastDigitFixed assumes d contains the representation of the integral part |  | ||||||
| // of some number, whose fractional part is num / (den << shift). The numerator |  | ||||||
| // num is only known up to an uncertainty of size ε, assumed to be less than |  | ||||||
| // (den << shift)/2. |  | ||||||
| // |  | ||||||
| // It will increase the last digit by one to account for correct rounding, typically |  | ||||||
| // when the fractional part is greater than 1/2, and will return false if ε is such |  | ||||||
| // that no correct answer can be given. |  | ||||||
| func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool { |  | ||||||
| 	if num > den<<shift { |  | ||||||
| 		panic("strconv: num > den<<shift in adjustLastDigitFixed") |  | ||||||
| 	} |  | ||||||
| 	if 2*ε > den<<shift { |  | ||||||
| 		panic("strconv: ε > (den<<shift)/2") |  | ||||||
| 	} |  | ||||||
| 	if 2*(num+ε) < den<<shift { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if 2*(num-ε) > den<<shift { |  | ||||||
| 		// increment d by 1. |  | ||||||
| 		i := d.nd - 1 |  | ||||||
| 		for ; i >= 0; i-- { |  | ||||||
| 			if d.d[i] == '9' { |  | ||||||
| 				d.nd-- |  | ||||||
| 			} else { |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if i < 0 { |  | ||||||
| 			d.d[0] = '1' |  | ||||||
| 			d.nd = 1 |  | ||||||
| 			d.dp++ |  | ||||||
| 		} else { |  | ||||||
| 			d.d[i]++ |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ShortestDecimal stores in d the shortest decimal representation of f |  | ||||||
| // which belongs to the open interval (lower, upper), where f is supposed |  | ||||||
| // to lie. It returns false whenever the result is unsure. The implementation |  | ||||||
| // uses the Grisu3 algorithm. |  | ||||||
| func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool { |  | ||||||
| 	if f.mant == 0 { |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		d.dp = 0 |  | ||||||
| 		d.neg = f.neg |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if f.exp == 0 && *lower == *f && *lower == *upper { |  | ||||||
| 		// an exact integer. |  | ||||||
| 		var buf [24]byte |  | ||||||
| 		n := len(buf) - 1 |  | ||||||
| 		for v := f.mant; v > 0; { |  | ||||||
| 			v1 := v / 10 |  | ||||||
| 			v -= 10 * v1 |  | ||||||
| 			buf[n] = byte(v + '0') |  | ||||||
| 			n-- |  | ||||||
| 			v = v1 |  | ||||||
| 		} |  | ||||||
| 		nd := len(buf) - n - 1 |  | ||||||
| 		for i := 0; i < nd; i++ { |  | ||||||
| 			d.d[i] = buf[n+1+i] |  | ||||||
| 		} |  | ||||||
| 		d.nd, d.dp = nd, nd |  | ||||||
| 		for d.nd > 0 && d.d[d.nd-1] == '0' { |  | ||||||
| 			d.nd-- |  | ||||||
| 		} |  | ||||||
| 		if d.nd == 0 { |  | ||||||
| 			d.dp = 0 |  | ||||||
| 		} |  | ||||||
| 		d.neg = f.neg |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	upper.Normalize() |  | ||||||
| 	// Uniformize exponents. |  | ||||||
| 	if f.exp > upper.exp { |  | ||||||
| 		f.mant <<= uint(f.exp - upper.exp) |  | ||||||
| 		f.exp = upper.exp |  | ||||||
| 	} |  | ||||||
| 	if lower.exp > upper.exp { |  | ||||||
| 		lower.mant <<= uint(lower.exp - upper.exp) |  | ||||||
| 		lower.exp = upper.exp |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	exp10 := frexp10Many(lower, f, upper) |  | ||||||
| 	// Take a safety margin due to rounding in frexp10Many, but we lose precision. |  | ||||||
| 	upper.mant++ |  | ||||||
| 	lower.mant-- |  | ||||||
|  |  | ||||||
| 	// The shortest representation of f is either rounded up or down, but |  | ||||||
| 	// in any case, it is a truncation of upper. |  | ||||||
| 	shift := uint(-upper.exp) |  | ||||||
| 	integer := uint32(upper.mant >> shift) |  | ||||||
| 	fraction := upper.mant - (uint64(integer) << shift) |  | ||||||
|  |  | ||||||
| 	// How far we can go down from upper until the result is wrong. |  | ||||||
| 	allowance := upper.mant - lower.mant |  | ||||||
| 	// How far we should go to get a very precise result. |  | ||||||
| 	targetDiff := upper.mant - f.mant |  | ||||||
|  |  | ||||||
| 	// Count integral digits: there are at most 10. |  | ||||||
| 	var integerDigits int |  | ||||||
| 	for i, pow := 0, uint64(1); i < 20; i++ { |  | ||||||
| 		if pow > uint64(integer) { |  | ||||||
| 			integerDigits = i |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		pow *= 10 |  | ||||||
| 	} |  | ||||||
| 	for i := 0; i < integerDigits; i++ { |  | ||||||
| 		pow := uint64pow10[integerDigits-i-1] |  | ||||||
| 		digit := integer / uint32(pow) |  | ||||||
| 		d.d[i] = byte(digit + '0') |  | ||||||
| 		integer -= digit * uint32(pow) |  | ||||||
| 		// evaluate whether we should stop. |  | ||||||
| 		if currentDiff := uint64(integer)<<shift + fraction; currentDiff < allowance { |  | ||||||
| 			d.nd = i + 1 |  | ||||||
| 			d.dp = integerDigits + exp10 |  | ||||||
| 			d.neg = f.neg |  | ||||||
| 			// Sometimes allowance is so large the last digit might need to be |  | ||||||
| 			// decremented to get closer to f. |  | ||||||
| 			return adjustLastDigit(d, currentDiff, targetDiff, allowance, pow<<shift, 2) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	d.nd = integerDigits |  | ||||||
| 	d.dp = d.nd + exp10 |  | ||||||
| 	d.neg = f.neg |  | ||||||
|  |  | ||||||
| 	// Compute digits of the fractional part. At each step fraction does not |  | ||||||
| 	// overflow. The choice of minExp implies that fraction is less than 2^60. |  | ||||||
| 	var digit int |  | ||||||
| 	multiplier := uint64(1) |  | ||||||
| 	for { |  | ||||||
| 		fraction *= 10 |  | ||||||
| 		multiplier *= 10 |  | ||||||
| 		digit = int(fraction >> shift) |  | ||||||
| 		d.d[d.nd] = byte(digit + '0') |  | ||||||
| 		d.nd++ |  | ||||||
| 		fraction -= uint64(digit) << shift |  | ||||||
| 		if fraction < allowance*multiplier { |  | ||||||
| 			// We are in the admissible range. Note that if allowance is about to |  | ||||||
| 			// overflow, that is, allowance > 2^64/10, the condition is automatically |  | ||||||
| 			// true due to the limited range of fraction. |  | ||||||
| 			return adjustLastDigit(d, |  | ||||||
| 				fraction, targetDiff*multiplier, allowance*multiplier, |  | ||||||
| 				1<<shift, multiplier*2) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // adjustLastDigit modifies d = x-currentDiff*ε, to get closest to |  | ||||||
| // d = x-targetDiff*ε, without becoming smaller than x-maxDiff*ε. |  | ||||||
| // It assumes that a decimal digit is worth ulpDecimal*ε, and that |  | ||||||
| // all data is known with a error estimate of ulpBinary*ε. |  | ||||||
| func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool { |  | ||||||
| 	if ulpDecimal < 2*ulpBinary { |  | ||||||
| 		// Approximation is too wide. |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for currentDiff+ulpDecimal/2+ulpBinary < targetDiff { |  | ||||||
| 		d.d[d.nd-1]-- |  | ||||||
| 		currentDiff += ulpDecimal |  | ||||||
| 	} |  | ||||||
| 	if currentDiff+ulpDecimal <= targetDiff+ulpDecimal/2+ulpBinary { |  | ||||||
| 		// we have two choices, and don't know what to do. |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if currentDiff < ulpBinary || currentDiff > maxDiff-ulpBinary { |  | ||||||
| 		// we went too far |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if d.nd == 1 && d.d[0] == '0' { |  | ||||||
| 		// the number has actually reached zero. |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		d.dp = 0 |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
							
								
								
									
										121
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/fold.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										121
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/fold.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,121 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Portions of this file are on Go stdlib's encoding/json/fold.go */ |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"unicode/utf8" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII. |  | ||||||
| 	kelvin       = '\u212a' |  | ||||||
| 	smallLongEss = '\u017f' |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // equalFoldRight is a specialization of bytes.EqualFold when s is |  | ||||||
| // known to be all ASCII (including punctuation), but contains an 's', |  | ||||||
| // 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. |  | ||||||
| // See comments on foldFunc. |  | ||||||
| func EqualFoldRight(s, t []byte) bool { |  | ||||||
| 	for _, sb := range s { |  | ||||||
| 		if len(t) == 0 { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		tb := t[0] |  | ||||||
| 		if tb < utf8.RuneSelf { |  | ||||||
| 			if sb != tb { |  | ||||||
| 				sbUpper := sb & caseMask |  | ||||||
| 				if 'A' <= sbUpper && sbUpper <= 'Z' { |  | ||||||
| 					if sbUpper != tb&caseMask { |  | ||||||
| 						return false |  | ||||||
| 					} |  | ||||||
| 				} else { |  | ||||||
| 					return false |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			t = t[1:] |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		// sb is ASCII and t is not. t must be either kelvin |  | ||||||
| 		// sign or long s; sb must be s, S, k, or K. |  | ||||||
| 		tr, size := utf8.DecodeRune(t) |  | ||||||
| 		switch sb { |  | ||||||
| 		case 's', 'S': |  | ||||||
| 			if tr != smallLongEss { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		case 'k', 'K': |  | ||||||
| 			if tr != kelvin { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		t = t[size:] |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
| 	if len(t) > 0 { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // asciiEqualFold is a specialization of bytes.EqualFold for use when |  | ||||||
| // s is all ASCII (but may contain non-letters) and contains no |  | ||||||
| // special-folding letters. |  | ||||||
| // See comments on foldFunc. |  | ||||||
| func AsciiEqualFold(s, t []byte) bool { |  | ||||||
| 	if len(s) != len(t) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, sb := range s { |  | ||||||
| 		tb := t[i] |  | ||||||
| 		if sb == tb { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { |  | ||||||
| 			if sb&caseMask != tb&caseMask { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // simpleLetterEqualFold is a specialization of bytes.EqualFold for |  | ||||||
| // use when s is all ASCII letters (no underscores, etc) and also |  | ||||||
| // doesn't contain 'k', 'K', 's', or 'S'. |  | ||||||
| // See comments on foldFunc. |  | ||||||
| func SimpleLetterEqualFold(s, t []byte) bool { |  | ||||||
| 	if len(s) != len(t) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, b := range s { |  | ||||||
| 		if b&caseMask != t[i]&caseMask { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
							
								
								
									
										542
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/ftoa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										542
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/ftoa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,542 +0,0 @@ | |||||||
| package v1 |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  *  Copyright 2015 Paul Querna, Klaus Post |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Most of this file are on Go stdlib's strconv/ftoa.go */ |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| import "math" |  | ||||||
|  |  | ||||||
| // TODO: move elsewhere? |  | ||||||
| type floatInfo struct { |  | ||||||
| 	mantbits uint |  | ||||||
| 	expbits  uint |  | ||||||
| 	bias     int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var optimize = true // can change for testing |  | ||||||
|  |  | ||||||
| var float32info = floatInfo{23, 8, -127} |  | ||||||
| var float64info = floatInfo{52, 11, -1023} |  | ||||||
|  |  | ||||||
| // AppendFloat appends the string form of the floating-point number f, |  | ||||||
| // as generated by FormatFloat |  | ||||||
| func AppendFloat(dst EncodingBuffer, val float64, fmt byte, prec, bitSize int) { |  | ||||||
| 	var bits uint64 |  | ||||||
| 	var flt *floatInfo |  | ||||||
| 	switch bitSize { |  | ||||||
| 	case 32: |  | ||||||
| 		bits = uint64(math.Float32bits(float32(val))) |  | ||||||
| 		flt = &float32info |  | ||||||
| 	case 64: |  | ||||||
| 		bits = math.Float64bits(val) |  | ||||||
| 		flt = &float64info |  | ||||||
| 	default: |  | ||||||
| 		panic("strconv: illegal AppendFloat/FormatFloat bitSize") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	neg := bits>>(flt.expbits+flt.mantbits) != 0 |  | ||||||
| 	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1) |  | ||||||
| 	mant := bits & (uint64(1)<<flt.mantbits - 1) |  | ||||||
|  |  | ||||||
| 	switch exp { |  | ||||||
| 	case 1<<flt.expbits - 1: |  | ||||||
| 		// Inf, NaN |  | ||||||
| 		var s string |  | ||||||
| 		switch { |  | ||||||
| 		case mant != 0: |  | ||||||
| 			s = "NaN" |  | ||||||
| 		case neg: |  | ||||||
| 			s = "-Inf" |  | ||||||
| 		default: |  | ||||||
| 			s = "+Inf" |  | ||||||
| 		} |  | ||||||
| 		dst.WriteString(s) |  | ||||||
| 		return |  | ||||||
|  |  | ||||||
| 	case 0: |  | ||||||
| 		// denormalized |  | ||||||
| 		exp++ |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		// add implicit top bit |  | ||||||
| 		mant |= uint64(1) << flt.mantbits |  | ||||||
| 	} |  | ||||||
| 	exp += flt.bias |  | ||||||
|  |  | ||||||
| 	// Pick off easy binary format. |  | ||||||
| 	if fmt == 'b' { |  | ||||||
| 		fmtB(dst, neg, mant, exp, flt) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !optimize { |  | ||||||
| 		bigFtoa(dst, prec, fmt, neg, mant, exp, flt) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var digs decimalSlice |  | ||||||
| 	ok := false |  | ||||||
| 	// Negative precision means "only as much as needed to be exact." |  | ||||||
| 	shortest := prec < 0 |  | ||||||
| 	if shortest { |  | ||||||
| 		// Try Grisu3 algorithm. |  | ||||||
| 		f := new(extFloat) |  | ||||||
| 		lower, upper := f.AssignComputeBounds(mant, exp, neg, flt) |  | ||||||
| 		var buf [32]byte |  | ||||||
| 		digs.d = buf[:] |  | ||||||
| 		ok = f.ShortestDecimal(&digs, &lower, &upper) |  | ||||||
| 		if !ok { |  | ||||||
| 			bigFtoa(dst, prec, fmt, neg, mant, exp, flt) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		// Precision for shortest representation mode. |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			prec = max(digs.nd-1, 0) |  | ||||||
| 		case 'f': |  | ||||||
| 			prec = max(digs.nd-digs.dp, 0) |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			prec = digs.nd |  | ||||||
| 		} |  | ||||||
| 	} else if fmt != 'f' { |  | ||||||
| 		// Fixed number of digits. |  | ||||||
| 		digits := prec |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			digits++ |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			if prec == 0 { |  | ||||||
| 				prec = 1 |  | ||||||
| 			} |  | ||||||
| 			digits = prec |  | ||||||
| 		} |  | ||||||
| 		if digits <= 15 { |  | ||||||
| 			// try fast algorithm when the number of digits is reasonable. |  | ||||||
| 			var buf [24]byte |  | ||||||
| 			digs.d = buf[:] |  | ||||||
| 			f := extFloat{mant, exp - int(flt.mantbits), neg} |  | ||||||
| 			ok = f.FixedDecimal(&digs, digits) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if !ok { |  | ||||||
| 		bigFtoa(dst, prec, fmt, neg, mant, exp, flt) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	formatDigits(dst, shortest, neg, digs, prec, fmt) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // bigFtoa uses multiprecision computations to format a float. |  | ||||||
| func bigFtoa(dst EncodingBuffer, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) { |  | ||||||
| 	d := new(decimal) |  | ||||||
| 	d.Assign(mant) |  | ||||||
| 	d.Shift(exp - int(flt.mantbits)) |  | ||||||
| 	var digs decimalSlice |  | ||||||
| 	shortest := prec < 0 |  | ||||||
| 	if shortest { |  | ||||||
| 		roundShortest(d, mant, exp, flt) |  | ||||||
| 		digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp} |  | ||||||
| 		// Precision for shortest representation mode. |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			prec = digs.nd - 1 |  | ||||||
| 		case 'f': |  | ||||||
| 			prec = max(digs.nd-digs.dp, 0) |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			prec = digs.nd |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		// Round appropriately. |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			d.Round(prec + 1) |  | ||||||
| 		case 'f': |  | ||||||
| 			d.Round(d.dp + prec) |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			if prec == 0 { |  | ||||||
| 				prec = 1 |  | ||||||
| 			} |  | ||||||
| 			d.Round(prec) |  | ||||||
| 		} |  | ||||||
| 		digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp} |  | ||||||
| 	} |  | ||||||
| 	formatDigits(dst, shortest, neg, digs, prec, fmt) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func formatDigits(dst EncodingBuffer, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) { |  | ||||||
| 	switch fmt { |  | ||||||
| 	case 'e', 'E': |  | ||||||
| 		fmtE(dst, neg, digs, prec, fmt) |  | ||||||
| 		return |  | ||||||
| 	case 'f': |  | ||||||
| 		fmtF(dst, neg, digs, prec) |  | ||||||
| 		return |  | ||||||
| 	case 'g', 'G': |  | ||||||
| 		// trailing fractional zeros in 'e' form will be trimmed. |  | ||||||
| 		eprec := prec |  | ||||||
| 		if eprec > digs.nd && digs.nd >= digs.dp { |  | ||||||
| 			eprec = digs.nd |  | ||||||
| 		} |  | ||||||
| 		// %e is used if the exponent from the conversion |  | ||||||
| 		// is less than -4 or greater than or equal to the precision. |  | ||||||
| 		// if precision was the shortest possible, use precision 6 for this decision. |  | ||||||
| 		if shortest { |  | ||||||
| 			eprec = 6 |  | ||||||
| 		} |  | ||||||
| 		exp := digs.dp - 1 |  | ||||||
| 		if exp < -4 || exp >= eprec { |  | ||||||
| 			if prec > digs.nd { |  | ||||||
| 				prec = digs.nd |  | ||||||
| 			} |  | ||||||
| 			fmtE(dst, neg, digs, prec-1, fmt+'e'-'g') |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		if prec > digs.dp { |  | ||||||
| 			prec = digs.nd |  | ||||||
| 		} |  | ||||||
| 		fmtF(dst, neg, digs, max(prec-digs.dp, 0)) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// unknown format |  | ||||||
| 	dst.Write([]byte{'%', fmt}) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round d (= mant * 2^exp) to the shortest number of digits |  | ||||||
| // that will let the original floating point value be precisely |  | ||||||
| // reconstructed.  Size is original floating point size (64 or 32). |  | ||||||
| func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { |  | ||||||
| 	// If mantissa is zero, the number is zero; stop now. |  | ||||||
| 	if mant == 0 { |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Compute upper and lower such that any decimal number |  | ||||||
| 	// between upper and lower (possibly inclusive) |  | ||||||
| 	// will round to the original floating point number. |  | ||||||
|  |  | ||||||
| 	// We may see at once that the number is already shortest. |  | ||||||
| 	// |  | ||||||
| 	// Suppose d is not denormal, so that 2^exp <= d < 10^dp. |  | ||||||
| 	// The closest shorter number is at least 10^(dp-nd) away. |  | ||||||
| 	// The lower/upper bounds computed below are at distance |  | ||||||
| 	// at most 2^(exp-mantbits). |  | ||||||
| 	// |  | ||||||
| 	// So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits), |  | ||||||
| 	// or equivalently log2(10)*(dp-nd) > exp-mantbits. |  | ||||||
| 	// It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32). |  | ||||||
| 	minexp := flt.bias + 1 // minimum possible exponent |  | ||||||
| 	if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) { |  | ||||||
| 		// The number is already shortest. |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// d = mant << (exp - mantbits) |  | ||||||
| 	// Next highest floating point number is mant+1 << exp-mantbits. |  | ||||||
| 	// Our upper bound is halfway between, mant*2+1 << exp-mantbits-1. |  | ||||||
| 	upper := new(decimal) |  | ||||||
| 	upper.Assign(mant*2 + 1) |  | ||||||
| 	upper.Shift(exp - int(flt.mantbits) - 1) |  | ||||||
|  |  | ||||||
| 	// d = mant << (exp - mantbits) |  | ||||||
| 	// Next lowest floating point number is mant-1 << exp-mantbits, |  | ||||||
| 	// unless mant-1 drops the significant bit and exp is not the minimum exp, |  | ||||||
| 	// in which case the next lowest is mant*2-1 << exp-mantbits-1. |  | ||||||
| 	// Either way, call it mantlo << explo-mantbits. |  | ||||||
| 	// Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1. |  | ||||||
| 	var mantlo uint64 |  | ||||||
| 	var explo int |  | ||||||
| 	if mant > 1<<flt.mantbits || exp == minexp { |  | ||||||
| 		mantlo = mant - 1 |  | ||||||
| 		explo = exp |  | ||||||
| 	} else { |  | ||||||
| 		mantlo = mant*2 - 1 |  | ||||||
| 		explo = exp - 1 |  | ||||||
| 	} |  | ||||||
| 	lower := new(decimal) |  | ||||||
| 	lower.Assign(mantlo*2 + 1) |  | ||||||
| 	lower.Shift(explo - int(flt.mantbits) - 1) |  | ||||||
|  |  | ||||||
| 	// The upper and lower bounds are possible outputs only if |  | ||||||
| 	// the original mantissa is even, so that IEEE round-to-even |  | ||||||
| 	// would round to the original mantissa and not the neighbors. |  | ||||||
| 	inclusive := mant%2 == 0 |  | ||||||
|  |  | ||||||
| 	// Now we can figure out the minimum number of digits required. |  | ||||||
| 	// Walk along until d has distinguished itself from upper and lower. |  | ||||||
| 	for i := 0; i < d.nd; i++ { |  | ||||||
| 		var l, m, u byte // lower, middle, upper digits |  | ||||||
| 		if i < lower.nd { |  | ||||||
| 			l = lower.d[i] |  | ||||||
| 		} else { |  | ||||||
| 			l = '0' |  | ||||||
| 		} |  | ||||||
| 		m = d.d[i] |  | ||||||
| 		if i < upper.nd { |  | ||||||
| 			u = upper.d[i] |  | ||||||
| 		} else { |  | ||||||
| 			u = '0' |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Okay to round down (truncate) if lower has a different digit |  | ||||||
| 		// or if lower is inclusive and is exactly the result of rounding down. |  | ||||||
| 		okdown := l != m || (inclusive && l == m && i+1 == lower.nd) |  | ||||||
|  |  | ||||||
| 		// Okay to round up if upper has a different digit and |  | ||||||
| 		// either upper is inclusive or upper is bigger than the result of rounding up. |  | ||||||
| 		okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd) |  | ||||||
|  |  | ||||||
| 		// If it's okay to do either, then round to the nearest one. |  | ||||||
| 		// If it's okay to do only one, do it. |  | ||||||
| 		switch { |  | ||||||
| 		case okdown && okup: |  | ||||||
| 			d.Round(i + 1) |  | ||||||
| 			return |  | ||||||
| 		case okdown: |  | ||||||
| 			d.RoundDown(i + 1) |  | ||||||
| 			return |  | ||||||
| 		case okup: |  | ||||||
| 			d.RoundUp(i + 1) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type decimalSlice struct { |  | ||||||
| 	d      []byte |  | ||||||
| 	nd, dp int |  | ||||||
| 	neg    bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // %e: -d.ddddde±dd |  | ||||||
| func fmtE(dst EncodingBuffer, neg bool, d decimalSlice, prec int, fmt byte) { |  | ||||||
| 	// sign |  | ||||||
| 	if neg { |  | ||||||
| 		dst.WriteByte('-') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// first digit |  | ||||||
| 	ch := byte('0') |  | ||||||
| 	if d.nd != 0 { |  | ||||||
| 		ch = d.d[0] |  | ||||||
| 	} |  | ||||||
| 	dst.WriteByte(ch) |  | ||||||
|  |  | ||||||
| 	// .moredigits |  | ||||||
| 	if prec > 0 { |  | ||||||
| 		dst.WriteByte('.') |  | ||||||
| 		i := 1 |  | ||||||
| 		m := min(d.nd, prec+1) |  | ||||||
| 		if i < m { |  | ||||||
| 			dst.Write(d.d[i:m]) |  | ||||||
| 			i = m |  | ||||||
| 		} |  | ||||||
| 		for i <= prec { |  | ||||||
| 			dst.WriteByte('0') |  | ||||||
| 			i++ |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// e± |  | ||||||
| 	dst.WriteByte(fmt) |  | ||||||
| 	exp := d.dp - 1 |  | ||||||
| 	if d.nd == 0 { // special case: 0 has exponent 0 |  | ||||||
| 		exp = 0 |  | ||||||
| 	} |  | ||||||
| 	if exp < 0 { |  | ||||||
| 		ch = '-' |  | ||||||
| 		exp = -exp |  | ||||||
| 	} else { |  | ||||||
| 		ch = '+' |  | ||||||
| 	} |  | ||||||
| 	dst.WriteByte(ch) |  | ||||||
|  |  | ||||||
| 	// dd or ddd |  | ||||||
| 	switch { |  | ||||||
| 	case exp < 10: |  | ||||||
| 		dst.WriteByte('0') |  | ||||||
| 		dst.WriteByte(byte(exp) + '0') |  | ||||||
| 	case exp < 100: |  | ||||||
| 		dst.WriteByte(byte(exp/10) + '0') |  | ||||||
| 		dst.WriteByte(byte(exp%10) + '0') |  | ||||||
| 	default: |  | ||||||
| 		dst.WriteByte(byte(exp/100) + '0') |  | ||||||
| 		dst.WriteByte(byte(exp/10)%10 + '0') |  | ||||||
| 		dst.WriteByte(byte(exp%10) + '0') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // %f: -ddddddd.ddddd |  | ||||||
| func fmtF(dst EncodingBuffer, neg bool, d decimalSlice, prec int) { |  | ||||||
| 	// sign |  | ||||||
| 	if neg { |  | ||||||
| 		dst.WriteByte('-') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// integer, padded with zeros as needed. |  | ||||||
| 	if d.dp > 0 { |  | ||||||
| 		m := min(d.nd, d.dp) |  | ||||||
| 		dst.Write(d.d[:m]) |  | ||||||
| 		for ; m < d.dp; m++ { |  | ||||||
| 			dst.WriteByte('0') |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		dst.WriteByte('0') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// fraction |  | ||||||
| 	if prec > 0 { |  | ||||||
| 		dst.WriteByte('.') |  | ||||||
| 		for i := 0; i < prec; i++ { |  | ||||||
| 			ch := byte('0') |  | ||||||
| 			if j := d.dp + i; 0 <= j && j < d.nd { |  | ||||||
| 				ch = d.d[j] |  | ||||||
| 			} |  | ||||||
| 			dst.WriteByte(ch) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // %b: -ddddddddp±ddd |  | ||||||
| func fmtB(dst EncodingBuffer, neg bool, mant uint64, exp int, flt *floatInfo) { |  | ||||||
| 	// sign |  | ||||||
| 	if neg { |  | ||||||
| 		dst.WriteByte('-') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// mantissa |  | ||||||
| 	formatBits(dst, mant, 10, false) |  | ||||||
|  |  | ||||||
| 	// p |  | ||||||
| 	dst.WriteByte('p') |  | ||||||
|  |  | ||||||
| 	// ±exponent |  | ||||||
| 	exp -= int(flt.mantbits) |  | ||||||
| 	if exp >= 0 { |  | ||||||
| 		dst.WriteByte('+') |  | ||||||
| 	} |  | ||||||
| 	formatBits(dst, uint64(exp), 10, exp < 0) |  | ||||||
|  |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func min(a, b int) int { |  | ||||||
| 	if a < b { |  | ||||||
| 		return a |  | ||||||
| 	} |  | ||||||
| 	return b |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func max(a, b int) int { |  | ||||||
| 	if a > b { |  | ||||||
| 		return a |  | ||||||
| 	} |  | ||||||
| 	return b |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // formatBits computes the string representation of u in the given base. |  | ||||||
| // If neg is set, u is treated as negative int64 value. |  | ||||||
| func formatBits(dst EncodingBuffer, u uint64, base int, neg bool) { |  | ||||||
| 	if base < 2 || base > len(digits) { |  | ||||||
| 		panic("strconv: illegal AppendInt/FormatInt base") |  | ||||||
| 	} |  | ||||||
| 	// 2 <= base && base <= len(digits) |  | ||||||
|  |  | ||||||
| 	var a [64 + 1]byte // +1 for sign of 64bit value in base 2 |  | ||||||
| 	i := len(a) |  | ||||||
|  |  | ||||||
| 	if neg { |  | ||||||
| 		u = -u |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// convert bits |  | ||||||
| 	if base == 10 { |  | ||||||
| 		// common case: use constants for / because |  | ||||||
| 		// the compiler can optimize it into a multiply+shift |  | ||||||
|  |  | ||||||
| 		if ^uintptr(0)>>32 == 0 { |  | ||||||
| 			for u > uint64(^uintptr(0)) { |  | ||||||
| 				q := u / 1e9 |  | ||||||
| 				us := uintptr(u - q*1e9) // us % 1e9 fits into a uintptr |  | ||||||
| 				for j := 9; j > 0; j-- { |  | ||||||
| 					i-- |  | ||||||
| 					qs := us / 10 |  | ||||||
| 					a[i] = byte(us - qs*10 + '0') |  | ||||||
| 					us = qs |  | ||||||
| 				} |  | ||||||
| 				u = q |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// u guaranteed to fit into a uintptr |  | ||||||
| 		us := uintptr(u) |  | ||||||
| 		for us >= 10 { |  | ||||||
| 			i-- |  | ||||||
| 			q := us / 10 |  | ||||||
| 			a[i] = byte(us - q*10 + '0') |  | ||||||
| 			us = q |  | ||||||
| 		} |  | ||||||
| 		// u < 10 |  | ||||||
| 		i-- |  | ||||||
| 		a[i] = byte(us + '0') |  | ||||||
|  |  | ||||||
| 	} else if s := shifts[base]; s > 0 { |  | ||||||
| 		// base is power of 2: use shifts and masks instead of / and % |  | ||||||
| 		b := uint64(base) |  | ||||||
| 		m := uintptr(b) - 1 // == 1<<s - 1 |  | ||||||
| 		for u >= b { |  | ||||||
| 			i-- |  | ||||||
| 			a[i] = digits[uintptr(u)&m] |  | ||||||
| 			u >>= s |  | ||||||
| 		} |  | ||||||
| 		// u < base |  | ||||||
| 		i-- |  | ||||||
| 		a[i] = digits[uintptr(u)] |  | ||||||
|  |  | ||||||
| 	} else { |  | ||||||
| 		// general case |  | ||||||
| 		b := uint64(base) |  | ||||||
| 		for u >= b { |  | ||||||
| 			i-- |  | ||||||
| 			q := u / b |  | ||||||
| 			a[i] = digits[uintptr(u-q*b)] |  | ||||||
| 			u = q |  | ||||||
| 		} |  | ||||||
| 		// u < base |  | ||||||
| 		i-- |  | ||||||
| 		a[i] = digits[uintptr(u)] |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// add sign, if any |  | ||||||
| 	if neg { |  | ||||||
| 		i-- |  | ||||||
| 		a[i] = '-' |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	dst.Write(a[i:]) |  | ||||||
| } |  | ||||||
							
								
								
									
										936
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/atof.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										936
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/atof.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,936 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Portions of this file are on Go stdlib's strconv/atof.go */ |  | ||||||
|  |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package internal |  | ||||||
|  |  | ||||||
| // decimal to binary floating point conversion. |  | ||||||
| // Algorithm: |  | ||||||
| //   1) Store input in multiprecision decimal. |  | ||||||
| //   2) Multiply/divide decimal by powers of two until in range [0.5, 1) |  | ||||||
| //   3) Multiply by 2^precision and round to get mantissa. |  | ||||||
|  |  | ||||||
| import "math" |  | ||||||
|  |  | ||||||
| var optimize = true // can change for testing |  | ||||||
|  |  | ||||||
| func equalIgnoreCase(s1 []byte, s2 []byte) bool { |  | ||||||
| 	if len(s1) != len(s2) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i := 0; i < len(s1); i++ { |  | ||||||
| 		c1 := s1[i] |  | ||||||
| 		if 'A' <= c1 && c1 <= 'Z' { |  | ||||||
| 			c1 += 'a' - 'A' |  | ||||||
| 		} |  | ||||||
| 		c2 := s2[i] |  | ||||||
| 		if 'A' <= c2 && c2 <= 'Z' { |  | ||||||
| 			c2 += 'a' - 'A' |  | ||||||
| 		} |  | ||||||
| 		if c1 != c2 { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func special(s []byte) (f float64, ok bool) { |  | ||||||
| 	if len(s) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	switch s[0] { |  | ||||||
| 	default: |  | ||||||
| 		return |  | ||||||
| 	case '+': |  | ||||||
| 		if equalIgnoreCase(s, []byte("+inf")) || equalIgnoreCase(s, []byte("+infinity")) { |  | ||||||
| 			return math.Inf(1), true |  | ||||||
| 		} |  | ||||||
| 	case '-': |  | ||||||
| 		if equalIgnoreCase(s, []byte("-inf")) || equalIgnoreCase(s, []byte("-infinity")) { |  | ||||||
| 			return math.Inf(-1), true |  | ||||||
| 		} |  | ||||||
| 	case 'n', 'N': |  | ||||||
| 		if equalIgnoreCase(s, []byte("nan")) { |  | ||||||
| 			return math.NaN(), true |  | ||||||
| 		} |  | ||||||
| 	case 'i', 'I': |  | ||||||
| 		if equalIgnoreCase(s, []byte("inf")) || equalIgnoreCase(s, []byte("infinity")) { |  | ||||||
| 			return math.Inf(1), true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (b *decimal) set(s []byte) (ok bool) { |  | ||||||
| 	i := 0 |  | ||||||
| 	b.neg = false |  | ||||||
| 	b.trunc = false |  | ||||||
|  |  | ||||||
| 	// optional sign |  | ||||||
| 	if i >= len(s) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	switch { |  | ||||||
| 	case s[i] == '+': |  | ||||||
| 		i++ |  | ||||||
| 	case s[i] == '-': |  | ||||||
| 		b.neg = true |  | ||||||
| 		i++ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// digits |  | ||||||
| 	sawdot := false |  | ||||||
| 	sawdigits := false |  | ||||||
| 	for ; i < len(s); i++ { |  | ||||||
| 		switch { |  | ||||||
| 		case s[i] == '.': |  | ||||||
| 			if sawdot { |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			sawdot = true |  | ||||||
| 			b.dp = b.nd |  | ||||||
| 			continue |  | ||||||
|  |  | ||||||
| 		case '0' <= s[i] && s[i] <= '9': |  | ||||||
| 			sawdigits = true |  | ||||||
| 			if s[i] == '0' && b.nd == 0 { // ignore leading zeros |  | ||||||
| 				b.dp-- |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			if b.nd < len(b.d) { |  | ||||||
| 				b.d[b.nd] = s[i] |  | ||||||
| 				b.nd++ |  | ||||||
| 			} else if s[i] != '0' { |  | ||||||
| 				b.trunc = true |  | ||||||
| 			} |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		break |  | ||||||
| 	} |  | ||||||
| 	if !sawdigits { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if !sawdot { |  | ||||||
| 		b.dp = b.nd |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// optional exponent moves decimal point. |  | ||||||
| 	// if we read a very large, very long number, |  | ||||||
| 	// just be sure to move the decimal point by |  | ||||||
| 	// a lot (say, 100000).  it doesn't matter if it's |  | ||||||
| 	// not the exact number. |  | ||||||
| 	if i < len(s) && (s[i] == 'e' || s[i] == 'E') { |  | ||||||
| 		i++ |  | ||||||
| 		if i >= len(s) { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		esign := 1 |  | ||||||
| 		if s[i] == '+' { |  | ||||||
| 			i++ |  | ||||||
| 		} else if s[i] == '-' { |  | ||||||
| 			i++ |  | ||||||
| 			esign = -1 |  | ||||||
| 		} |  | ||||||
| 		if i >= len(s) || s[i] < '0' || s[i] > '9' { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		e := 0 |  | ||||||
| 		for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { |  | ||||||
| 			if e < 10000 { |  | ||||||
| 				e = e*10 + int(s[i]) - '0' |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		b.dp += e * esign |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if i != len(s) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ok = true |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // readFloat reads a decimal mantissa and exponent from a float |  | ||||||
| // string representation. It sets ok to false if the number could |  | ||||||
| // not fit return types or is invalid. |  | ||||||
| func readFloat(s []byte) (mantissa uint64, exp int, neg, trunc, ok bool) { |  | ||||||
| 	const uint64digits = 19 |  | ||||||
| 	i := 0 |  | ||||||
|  |  | ||||||
| 	// optional sign |  | ||||||
| 	if i >= len(s) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	switch { |  | ||||||
| 	case s[i] == '+': |  | ||||||
| 		i++ |  | ||||||
| 	case s[i] == '-': |  | ||||||
| 		neg = true |  | ||||||
| 		i++ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// digits |  | ||||||
| 	sawdot := false |  | ||||||
| 	sawdigits := false |  | ||||||
| 	nd := 0 |  | ||||||
| 	ndMant := 0 |  | ||||||
| 	dp := 0 |  | ||||||
| 	for ; i < len(s); i++ { |  | ||||||
| 		switch c := s[i]; true { |  | ||||||
| 		case c == '.': |  | ||||||
| 			if sawdot { |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			sawdot = true |  | ||||||
| 			dp = nd |  | ||||||
| 			continue |  | ||||||
|  |  | ||||||
| 		case '0' <= c && c <= '9': |  | ||||||
| 			sawdigits = true |  | ||||||
| 			if c == '0' && nd == 0 { // ignore leading zeros |  | ||||||
| 				dp-- |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			nd++ |  | ||||||
| 			if ndMant < uint64digits { |  | ||||||
| 				mantissa *= 10 |  | ||||||
| 				mantissa += uint64(c - '0') |  | ||||||
| 				ndMant++ |  | ||||||
| 			} else if s[i] != '0' { |  | ||||||
| 				trunc = true |  | ||||||
| 			} |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		break |  | ||||||
| 	} |  | ||||||
| 	if !sawdigits { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if !sawdot { |  | ||||||
| 		dp = nd |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// optional exponent moves decimal point. |  | ||||||
| 	// if we read a very large, very long number, |  | ||||||
| 	// just be sure to move the decimal point by |  | ||||||
| 	// a lot (say, 100000).  it doesn't matter if it's |  | ||||||
| 	// not the exact number. |  | ||||||
| 	if i < len(s) && (s[i] == 'e' || s[i] == 'E') { |  | ||||||
| 		i++ |  | ||||||
| 		if i >= len(s) { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		esign := 1 |  | ||||||
| 		if s[i] == '+' { |  | ||||||
| 			i++ |  | ||||||
| 		} else if s[i] == '-' { |  | ||||||
| 			i++ |  | ||||||
| 			esign = -1 |  | ||||||
| 		} |  | ||||||
| 		if i >= len(s) || s[i] < '0' || s[i] > '9' { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		e := 0 |  | ||||||
| 		for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { |  | ||||||
| 			if e < 10000 { |  | ||||||
| 				e = e*10 + int(s[i]) - '0' |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		dp += e * esign |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if i != len(s) { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	exp = dp - ndMant |  | ||||||
| 	ok = true |  | ||||||
| 	return |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // decimal power of ten to binary power of two. |  | ||||||
| var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26} |  | ||||||
|  |  | ||||||
| func (d *decimal) floatBits(flt *floatInfo) (b uint64, overflow bool) { |  | ||||||
| 	var exp int |  | ||||||
| 	var mant uint64 |  | ||||||
|  |  | ||||||
| 	// Zero is always a special case. |  | ||||||
| 	if d.nd == 0 { |  | ||||||
| 		mant = 0 |  | ||||||
| 		exp = flt.bias |  | ||||||
| 		goto out |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Obvious overflow/underflow. |  | ||||||
| 	// These bounds are for 64-bit floats. |  | ||||||
| 	// Will have to change if we want to support 80-bit floats in the future. |  | ||||||
| 	if d.dp > 310 { |  | ||||||
| 		goto overflow |  | ||||||
| 	} |  | ||||||
| 	if d.dp < -330 { |  | ||||||
| 		// zero |  | ||||||
| 		mant = 0 |  | ||||||
| 		exp = flt.bias |  | ||||||
| 		goto out |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Scale by powers of two until in range [0.5, 1.0) |  | ||||||
| 	exp = 0 |  | ||||||
| 	for d.dp > 0 { |  | ||||||
| 		var n int |  | ||||||
| 		if d.dp >= len(powtab) { |  | ||||||
| 			n = 27 |  | ||||||
| 		} else { |  | ||||||
| 			n = powtab[d.dp] |  | ||||||
| 		} |  | ||||||
| 		d.Shift(-n) |  | ||||||
| 		exp += n |  | ||||||
| 	} |  | ||||||
| 	for d.dp < 0 || d.dp == 0 && d.d[0] < '5' { |  | ||||||
| 		var n int |  | ||||||
| 		if -d.dp >= len(powtab) { |  | ||||||
| 			n = 27 |  | ||||||
| 		} else { |  | ||||||
| 			n = powtab[-d.dp] |  | ||||||
| 		} |  | ||||||
| 		d.Shift(n) |  | ||||||
| 		exp -= n |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Our range is [0.5,1) but floating point range is [1,2). |  | ||||||
| 	exp-- |  | ||||||
|  |  | ||||||
| 	// Minimum representable exponent is flt.bias+1. |  | ||||||
| 	// If the exponent is smaller, move it up and |  | ||||||
| 	// adjust d accordingly. |  | ||||||
| 	if exp < flt.bias+1 { |  | ||||||
| 		n := flt.bias + 1 - exp |  | ||||||
| 		d.Shift(-n) |  | ||||||
| 		exp += n |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if exp-flt.bias >= 1<<flt.expbits-1 { |  | ||||||
| 		goto overflow |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Extract 1+flt.mantbits bits. |  | ||||||
| 	d.Shift(int(1 + flt.mantbits)) |  | ||||||
| 	mant = d.RoundedInteger() |  | ||||||
|  |  | ||||||
| 	// Rounding might have added a bit; shift down. |  | ||||||
| 	if mant == 2<<flt.mantbits { |  | ||||||
| 		mant >>= 1 |  | ||||||
| 		exp++ |  | ||||||
| 		if exp-flt.bias >= 1<<flt.expbits-1 { |  | ||||||
| 			goto overflow |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Denormalized? |  | ||||||
| 	if mant&(1<<flt.mantbits) == 0 { |  | ||||||
| 		exp = flt.bias |  | ||||||
| 	} |  | ||||||
| 	goto out |  | ||||||
|  |  | ||||||
| overflow: |  | ||||||
| 	// ±Inf |  | ||||||
| 	mant = 0 |  | ||||||
| 	exp = 1<<flt.expbits - 1 + flt.bias |  | ||||||
| 	overflow = true |  | ||||||
|  |  | ||||||
| out: |  | ||||||
| 	// Assemble bits. |  | ||||||
| 	bits := mant & (uint64(1)<<flt.mantbits - 1) |  | ||||||
| 	bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits |  | ||||||
| 	if d.neg { |  | ||||||
| 		bits |= 1 << flt.mantbits << flt.expbits |  | ||||||
| 	} |  | ||||||
| 	return bits, overflow |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Exact powers of 10. |  | ||||||
| var float64pow10 = []float64{ |  | ||||||
| 	1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, |  | ||||||
| 	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, |  | ||||||
| 	1e20, 1e21, 1e22, |  | ||||||
| } |  | ||||||
| var float32pow10 = []float32{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10} |  | ||||||
|  |  | ||||||
| // If possible to convert decimal representation to 64-bit float f exactly, |  | ||||||
| // entirely in floating-point math, do so, avoiding the expense of decimalToFloatBits. |  | ||||||
| // Three common cases: |  | ||||||
| //	value is exact integer |  | ||||||
| //	value is exact integer * exact power of ten |  | ||||||
| //	value is exact integer / exact power of ten |  | ||||||
| // These all produce potentially inexact but correctly rounded answers. |  | ||||||
| func atof64exact(mantissa uint64, exp int, neg bool) (f float64, ok bool) { |  | ||||||
| 	if mantissa>>float64info.mantbits != 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	f = float64(mantissa) |  | ||||||
| 	if neg { |  | ||||||
| 		f = -f |  | ||||||
| 	} |  | ||||||
| 	switch { |  | ||||||
| 	case exp == 0: |  | ||||||
| 		// an integer. |  | ||||||
| 		return f, true |  | ||||||
| 	// Exact integers are <= 10^15. |  | ||||||
| 	// Exact powers of ten are <= 10^22. |  | ||||||
| 	case exp > 0 && exp <= 15+22: // int * 10^k |  | ||||||
| 		// If exponent is big but number of digits is not, |  | ||||||
| 		// can move a few zeros into the integer part. |  | ||||||
| 		if exp > 22 { |  | ||||||
| 			f *= float64pow10[exp-22] |  | ||||||
| 			exp = 22 |  | ||||||
| 		} |  | ||||||
| 		if f > 1e15 || f < -1e15 { |  | ||||||
| 			// the exponent was really too large. |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		return f * float64pow10[exp], true |  | ||||||
| 	case exp < 0 && exp >= -22: // int / 10^k |  | ||||||
| 		return f / float64pow10[-exp], true |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // If possible to compute mantissa*10^exp to 32-bit float f exactly, |  | ||||||
| // entirely in floating-point math, do so, avoiding the machinery above. |  | ||||||
| func atof32exact(mantissa uint64, exp int, neg bool) (f float32, ok bool) { |  | ||||||
| 	if mantissa>>float32info.mantbits != 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	f = float32(mantissa) |  | ||||||
| 	if neg { |  | ||||||
| 		f = -f |  | ||||||
| 	} |  | ||||||
| 	switch { |  | ||||||
| 	case exp == 0: |  | ||||||
| 		return f, true |  | ||||||
| 	// Exact integers are <= 10^7. |  | ||||||
| 	// Exact powers of ten are <= 10^10. |  | ||||||
| 	case exp > 0 && exp <= 7+10: // int * 10^k |  | ||||||
| 		// If exponent is big but number of digits is not, |  | ||||||
| 		// can move a few zeros into the integer part. |  | ||||||
| 		if exp > 10 { |  | ||||||
| 			f *= float32pow10[exp-10] |  | ||||||
| 			exp = 10 |  | ||||||
| 		} |  | ||||||
| 		if f > 1e7 || f < -1e7 { |  | ||||||
| 			// the exponent was really too large. |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		return f * float32pow10[exp], true |  | ||||||
| 	case exp < 0 && exp >= -10: // int / 10^k |  | ||||||
| 		return f / float32pow10[-exp], true |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const fnParseFloat = "ParseFloat" |  | ||||||
|  |  | ||||||
| func atof32(s []byte) (f float32, err error) { |  | ||||||
| 	if val, ok := special(s); ok { |  | ||||||
| 		return float32(val), nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if optimize { |  | ||||||
| 		// Parse mantissa and exponent. |  | ||||||
| 		mantissa, exp, neg, trunc, ok := readFloat(s) |  | ||||||
| 		if ok { |  | ||||||
| 			// Try pure floating-point arithmetic conversion. |  | ||||||
| 			if !trunc { |  | ||||||
| 				if f, ok := atof32exact(mantissa, exp, neg); ok { |  | ||||||
| 					return f, nil |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			// Try another fast path. |  | ||||||
| 			ext := new(extFloat) |  | ||||||
| 			if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float32info); ok { |  | ||||||
| 				b, ovf := ext.floatBits(&float32info) |  | ||||||
| 				f = math.Float32frombits(uint32(b)) |  | ||||||
| 				if ovf { |  | ||||||
| 					err = rangeError(fnParseFloat, string(s)) |  | ||||||
| 				} |  | ||||||
| 				return f, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	var d decimal |  | ||||||
| 	if !d.set(s) { |  | ||||||
| 		return 0, syntaxError(fnParseFloat, string(s)) |  | ||||||
| 	} |  | ||||||
| 	b, ovf := d.floatBits(&float32info) |  | ||||||
| 	f = math.Float32frombits(uint32(b)) |  | ||||||
| 	if ovf { |  | ||||||
| 		err = rangeError(fnParseFloat, string(s)) |  | ||||||
| 	} |  | ||||||
| 	return f, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func atof64(s []byte) (f float64, err error) { |  | ||||||
| 	if val, ok := special(s); ok { |  | ||||||
| 		return val, nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if optimize { |  | ||||||
| 		// Parse mantissa and exponent. |  | ||||||
| 		mantissa, exp, neg, trunc, ok := readFloat(s) |  | ||||||
| 		if ok { |  | ||||||
| 			// Try pure floating-point arithmetic conversion. |  | ||||||
| 			if !trunc { |  | ||||||
| 				if f, ok := atof64exact(mantissa, exp, neg); ok { |  | ||||||
| 					return f, nil |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			// Try another fast path. |  | ||||||
| 			ext := new(extFloat) |  | ||||||
| 			if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float64info); ok { |  | ||||||
| 				b, ovf := ext.floatBits(&float64info) |  | ||||||
| 				f = math.Float64frombits(b) |  | ||||||
| 				if ovf { |  | ||||||
| 					err = rangeError(fnParseFloat, string(s)) |  | ||||||
| 				} |  | ||||||
| 				return f, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	var d decimal |  | ||||||
| 	if !d.set(s) { |  | ||||||
| 		return 0, syntaxError(fnParseFloat, string(s)) |  | ||||||
| 	} |  | ||||||
| 	b, ovf := d.floatBits(&float64info) |  | ||||||
| 	f = math.Float64frombits(b) |  | ||||||
| 	if ovf { |  | ||||||
| 		err = rangeError(fnParseFloat, string(s)) |  | ||||||
| 	} |  | ||||||
| 	return f, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ParseFloat converts the string s to a floating-point number |  | ||||||
| // with the precision specified by bitSize: 32 for float32, or 64 for float64. |  | ||||||
| // When bitSize=32, the result still has type float64, but it will be |  | ||||||
| // convertible to float32 without changing its value. |  | ||||||
| // |  | ||||||
| // If s is well-formed and near a valid floating point number, |  | ||||||
| // ParseFloat returns the nearest floating point number rounded |  | ||||||
| // using IEEE754 unbiased rounding. |  | ||||||
| // |  | ||||||
| // The errors that ParseFloat returns have concrete type *NumError |  | ||||||
| // and include err.Num = s. |  | ||||||
| // |  | ||||||
| // If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax. |  | ||||||
| // |  | ||||||
| // If s is syntactically well-formed but is more than 1/2 ULP |  | ||||||
| // away from the largest floating point number of the given size, |  | ||||||
| // ParseFloat returns f = ±Inf, err.Err = ErrRange. |  | ||||||
| func ParseFloat(s []byte, bitSize int) (f float64, err error) { |  | ||||||
| 	if bitSize == 32 { |  | ||||||
| 		f1, err1 := atof32(s) |  | ||||||
| 		return float64(f1), err1 |  | ||||||
| 	} |  | ||||||
| 	f1, err1 := atof64(s) |  | ||||||
| 	return f1, err1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // oroginal: strconv/decimal.go, but not exported, and needed for PareFloat. |  | ||||||
|  |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| // Multiprecision decimal numbers. |  | ||||||
| // For floating-point formatting only; not general purpose. |  | ||||||
| // Only operations are assign and (binary) left/right shift. |  | ||||||
| // Can do binary floating point in multiprecision decimal precisely |  | ||||||
| // because 2 divides 10; cannot do decimal floating point |  | ||||||
| // in multiprecision binary precisely. |  | ||||||
|  |  | ||||||
| type decimal struct { |  | ||||||
| 	d     [800]byte // digits |  | ||||||
| 	nd    int       // number of digits used |  | ||||||
| 	dp    int       // decimal point |  | ||||||
| 	neg   bool |  | ||||||
| 	trunc bool // discarded nonzero digits beyond d[:nd] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *decimal) String() string { |  | ||||||
| 	n := 10 + a.nd |  | ||||||
| 	if a.dp > 0 { |  | ||||||
| 		n += a.dp |  | ||||||
| 	} |  | ||||||
| 	if a.dp < 0 { |  | ||||||
| 		n += -a.dp |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	buf := make([]byte, n) |  | ||||||
| 	w := 0 |  | ||||||
| 	switch { |  | ||||||
| 	case a.nd == 0: |  | ||||||
| 		return "0" |  | ||||||
|  |  | ||||||
| 	case a.dp <= 0: |  | ||||||
| 		// zeros fill space between decimal point and digits |  | ||||||
| 		buf[w] = '0' |  | ||||||
| 		w++ |  | ||||||
| 		buf[w] = '.' |  | ||||||
| 		w++ |  | ||||||
| 		w += digitZero(buf[w : w+-a.dp]) |  | ||||||
| 		w += copy(buf[w:], a.d[0:a.nd]) |  | ||||||
|  |  | ||||||
| 	case a.dp < a.nd: |  | ||||||
| 		// decimal point in middle of digits |  | ||||||
| 		w += copy(buf[w:], a.d[0:a.dp]) |  | ||||||
| 		buf[w] = '.' |  | ||||||
| 		w++ |  | ||||||
| 		w += copy(buf[w:], a.d[a.dp:a.nd]) |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		// zeros fill space between digits and decimal point |  | ||||||
| 		w += copy(buf[w:], a.d[0:a.nd]) |  | ||||||
| 		w += digitZero(buf[w : w+a.dp-a.nd]) |  | ||||||
| 	} |  | ||||||
| 	return string(buf[0:w]) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func digitZero(dst []byte) int { |  | ||||||
| 	for i := range dst { |  | ||||||
| 		dst[i] = '0' |  | ||||||
| 	} |  | ||||||
| 	return len(dst) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // trim trailing zeros from number. |  | ||||||
| // (They are meaningless; the decimal point is tracked |  | ||||||
| // independent of the number of digits.) |  | ||||||
| func trim(a *decimal) { |  | ||||||
| 	for a.nd > 0 && a.d[a.nd-1] == '0' { |  | ||||||
| 		a.nd-- |  | ||||||
| 	} |  | ||||||
| 	if a.nd == 0 { |  | ||||||
| 		a.dp = 0 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Assign v to a. |  | ||||||
| func (a *decimal) Assign(v uint64) { |  | ||||||
| 	var buf [24]byte |  | ||||||
|  |  | ||||||
| 	// Write reversed decimal in buf. |  | ||||||
| 	n := 0 |  | ||||||
| 	for v > 0 { |  | ||||||
| 		v1 := v / 10 |  | ||||||
| 		v -= 10 * v1 |  | ||||||
| 		buf[n] = byte(v + '0') |  | ||||||
| 		n++ |  | ||||||
| 		v = v1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Reverse again to produce forward decimal in a.d. |  | ||||||
| 	a.nd = 0 |  | ||||||
| 	for n--; n >= 0; n-- { |  | ||||||
| 		a.d[a.nd] = buf[n] |  | ||||||
| 		a.nd++ |  | ||||||
| 	} |  | ||||||
| 	a.dp = a.nd |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Maximum shift that we can do in one pass without overflow. |  | ||||||
| // Signed int has 31 bits, and we have to be able to accommodate 9<<k. |  | ||||||
| const maxShift = 27 |  | ||||||
|  |  | ||||||
| // Binary shift right (* 2) by k bits.  k <= maxShift to avoid overflow. |  | ||||||
| func rightShift(a *decimal, k uint) { |  | ||||||
| 	r := 0 // read pointer |  | ||||||
| 	w := 0 // write pointer |  | ||||||
|  |  | ||||||
| 	// Pick up enough leading digits to cover first shift. |  | ||||||
| 	n := 0 |  | ||||||
| 	for ; n>>k == 0; r++ { |  | ||||||
| 		if r >= a.nd { |  | ||||||
| 			if n == 0 { |  | ||||||
| 				// a == 0; shouldn't get here, but handle anyway. |  | ||||||
| 				a.nd = 0 |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			for n>>k == 0 { |  | ||||||
| 				n = n * 10 |  | ||||||
| 				r++ |  | ||||||
| 			} |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		c := int(a.d[r]) |  | ||||||
| 		n = n*10 + c - '0' |  | ||||||
| 	} |  | ||||||
| 	a.dp -= r - 1 |  | ||||||
|  |  | ||||||
| 	// Pick up a digit, put down a digit. |  | ||||||
| 	for ; r < a.nd; r++ { |  | ||||||
| 		c := int(a.d[r]) |  | ||||||
| 		dig := n >> k |  | ||||||
| 		n -= dig << k |  | ||||||
| 		a.d[w] = byte(dig + '0') |  | ||||||
| 		w++ |  | ||||||
| 		n = n*10 + c - '0' |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Put down extra digits. |  | ||||||
| 	for n > 0 { |  | ||||||
| 		dig := n >> k |  | ||||||
| 		n -= dig << k |  | ||||||
| 		if w < len(a.d) { |  | ||||||
| 			a.d[w] = byte(dig + '0') |  | ||||||
| 			w++ |  | ||||||
| 		} else if dig > 0 { |  | ||||||
| 			a.trunc = true |  | ||||||
| 		} |  | ||||||
| 		n = n * 10 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	a.nd = w |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Cheat sheet for left shift: table indexed by shift count giving |  | ||||||
| // number of new digits that will be introduced by that shift. |  | ||||||
| // |  | ||||||
| // For example, leftcheats[4] = {2, "625"}.  That means that |  | ||||||
| // if we are shifting by 4 (multiplying by 16), it will add 2 digits |  | ||||||
| // when the string prefix is "625" through "999", and one fewer digit |  | ||||||
| // if the string prefix is "000" through "624". |  | ||||||
| // |  | ||||||
| // Credit for this trick goes to Ken. |  | ||||||
|  |  | ||||||
| type leftCheat struct { |  | ||||||
| 	delta  int    // number of new digits |  | ||||||
| 	cutoff string //   minus one digit if original < a. |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var leftcheats = []leftCheat{ |  | ||||||
| 	// Leading digits of 1/2^i = 5^i. |  | ||||||
| 	// 5^23 is not an exact 64-bit floating point number, |  | ||||||
| 	// so have to use bc for the math. |  | ||||||
| 	/* |  | ||||||
| 		seq 27 | sed 's/^/5^/' | bc | |  | ||||||
| 		awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," } |  | ||||||
| 		{ |  | ||||||
| 			log2 = log(2)/log(10) |  | ||||||
| 			printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n", |  | ||||||
| 				int(log2*NR+1), $0, 2**NR) |  | ||||||
| 		}' |  | ||||||
| 	*/ |  | ||||||
| 	{0, ""}, |  | ||||||
| 	{1, "5"},                   // * 2 |  | ||||||
| 	{1, "25"},                  // * 4 |  | ||||||
| 	{1, "125"},                 // * 8 |  | ||||||
| 	{2, "625"},                 // * 16 |  | ||||||
| 	{2, "3125"},                // * 32 |  | ||||||
| 	{2, "15625"},               // * 64 |  | ||||||
| 	{3, "78125"},               // * 128 |  | ||||||
| 	{3, "390625"},              // * 256 |  | ||||||
| 	{3, "1953125"},             // * 512 |  | ||||||
| 	{4, "9765625"},             // * 1024 |  | ||||||
| 	{4, "48828125"},            // * 2048 |  | ||||||
| 	{4, "244140625"},           // * 4096 |  | ||||||
| 	{4, "1220703125"},          // * 8192 |  | ||||||
| 	{5, "6103515625"},          // * 16384 |  | ||||||
| 	{5, "30517578125"},         // * 32768 |  | ||||||
| 	{5, "152587890625"},        // * 65536 |  | ||||||
| 	{6, "762939453125"},        // * 131072 |  | ||||||
| 	{6, "3814697265625"},       // * 262144 |  | ||||||
| 	{6, "19073486328125"},      // * 524288 |  | ||||||
| 	{7, "95367431640625"},      // * 1048576 |  | ||||||
| 	{7, "476837158203125"},     // * 2097152 |  | ||||||
| 	{7, "2384185791015625"},    // * 4194304 |  | ||||||
| 	{7, "11920928955078125"},   // * 8388608 |  | ||||||
| 	{8, "59604644775390625"},   // * 16777216 |  | ||||||
| 	{8, "298023223876953125"},  // * 33554432 |  | ||||||
| 	{8, "1490116119384765625"}, // * 67108864 |  | ||||||
| 	{9, "7450580596923828125"}, // * 134217728 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Is the leading prefix of b lexicographically less than s? |  | ||||||
| func prefixIsLessThan(b []byte, s string) bool { |  | ||||||
| 	for i := 0; i < len(s); i++ { |  | ||||||
| 		if i >= len(b) { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		if b[i] != s[i] { |  | ||||||
| 			return b[i] < s[i] |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Binary shift left (/ 2) by k bits.  k <= maxShift to avoid overflow. |  | ||||||
| func leftShift(a *decimal, k uint) { |  | ||||||
| 	delta := leftcheats[k].delta |  | ||||||
| 	if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) { |  | ||||||
| 		delta-- |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	r := a.nd         // read index |  | ||||||
| 	w := a.nd + delta // write index |  | ||||||
| 	n := 0 |  | ||||||
|  |  | ||||||
| 	// Pick up a digit, put down a digit. |  | ||||||
| 	for r--; r >= 0; r-- { |  | ||||||
| 		n += (int(a.d[r]) - '0') << k |  | ||||||
| 		quo := n / 10 |  | ||||||
| 		rem := n - 10*quo |  | ||||||
| 		w-- |  | ||||||
| 		if w < len(a.d) { |  | ||||||
| 			a.d[w] = byte(rem + '0') |  | ||||||
| 		} else if rem != 0 { |  | ||||||
| 			a.trunc = true |  | ||||||
| 		} |  | ||||||
| 		n = quo |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Put down extra digits. |  | ||||||
| 	for n > 0 { |  | ||||||
| 		quo := n / 10 |  | ||||||
| 		rem := n - 10*quo |  | ||||||
| 		w-- |  | ||||||
| 		if w < len(a.d) { |  | ||||||
| 			a.d[w] = byte(rem + '0') |  | ||||||
| 		} else if rem != 0 { |  | ||||||
| 			a.trunc = true |  | ||||||
| 		} |  | ||||||
| 		n = quo |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	a.nd += delta |  | ||||||
| 	if a.nd >= len(a.d) { |  | ||||||
| 		a.nd = len(a.d) |  | ||||||
| 	} |  | ||||||
| 	a.dp += delta |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Binary shift left (k > 0) or right (k < 0). |  | ||||||
| func (a *decimal) Shift(k int) { |  | ||||||
| 	switch { |  | ||||||
| 	case a.nd == 0: |  | ||||||
| 		// nothing to do: a == 0 |  | ||||||
| 	case k > 0: |  | ||||||
| 		for k > maxShift { |  | ||||||
| 			leftShift(a, maxShift) |  | ||||||
| 			k -= maxShift |  | ||||||
| 		} |  | ||||||
| 		leftShift(a, uint(k)) |  | ||||||
| 	case k < 0: |  | ||||||
| 		for k < -maxShift { |  | ||||||
| 			rightShift(a, maxShift) |  | ||||||
| 			k += maxShift |  | ||||||
| 		} |  | ||||||
| 		rightShift(a, uint(-k)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // If we chop a at nd digits, should we round up? |  | ||||||
| func shouldRoundUp(a *decimal, nd int) bool { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even |  | ||||||
| 		// if we truncated, a little higher than what's recorded - always round up |  | ||||||
| 		if a.trunc { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		return nd > 0 && (a.d[nd-1]-'0')%2 != 0 |  | ||||||
| 	} |  | ||||||
| 	// not halfway - digit tells all |  | ||||||
| 	return a.d[nd] >= '5' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round a to nd digits (or fewer). |  | ||||||
| // If nd is zero, it means we're rounding |  | ||||||
| // just to the left of the digits, as in |  | ||||||
| // 0.09 -> 0.1. |  | ||||||
| func (a *decimal) Round(nd int) { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if shouldRoundUp(a, nd) { |  | ||||||
| 		a.RoundUp(nd) |  | ||||||
| 	} else { |  | ||||||
| 		a.RoundDown(nd) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round a down to nd digits (or fewer). |  | ||||||
| func (a *decimal) RoundDown(nd int) { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	a.nd = nd |  | ||||||
| 	trim(a) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round a up to nd digits (or fewer). |  | ||||||
| func (a *decimal) RoundUp(nd int) { |  | ||||||
| 	if nd < 0 || nd >= a.nd { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// round up |  | ||||||
| 	for i := nd - 1; i >= 0; i-- { |  | ||||||
| 		c := a.d[i] |  | ||||||
| 		if c < '9' { // can stop after this digit |  | ||||||
| 			a.d[i]++ |  | ||||||
| 			a.nd = i + 1 |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Number is all 9s. |  | ||||||
| 	// Change to single 1 with adjusted decimal point. |  | ||||||
| 	a.d[0] = '1' |  | ||||||
| 	a.nd = 1 |  | ||||||
| 	a.dp++ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Extract integer part, rounded appropriately. |  | ||||||
| // No guarantees about overflow. |  | ||||||
| func (a *decimal) RoundedInteger() uint64 { |  | ||||||
| 	if a.dp > 20 { |  | ||||||
| 		return 0xFFFFFFFFFFFFFFFF |  | ||||||
| 	} |  | ||||||
| 	var i int |  | ||||||
| 	n := uint64(0) |  | ||||||
| 	for i = 0; i < a.dp && i < a.nd; i++ { |  | ||||||
| 		n = n*10 + uint64(a.d[i]-'0') |  | ||||||
| 	} |  | ||||||
| 	for ; i < a.dp; i++ { |  | ||||||
| 		n *= 10 |  | ||||||
| 	} |  | ||||||
| 	if shouldRoundUp(a, a.dp) { |  | ||||||
| 		n++ |  | ||||||
| 	} |  | ||||||
| 	return n |  | ||||||
| } |  | ||||||
							
								
								
									
										213
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/atoi.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										213
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/atoi.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,213 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Portions of this file are on Go stdlib's strconv/atoi.go */ |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package internal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // ErrRange indicates that a value is out of range for the target type. |  | ||||||
| var ErrRange = errors.New("value out of range") |  | ||||||
|  |  | ||||||
| // ErrSyntax indicates that a value does not have the right syntax for the target type. |  | ||||||
| var ErrSyntax = errors.New("invalid syntax") |  | ||||||
|  |  | ||||||
| // A NumError records a failed conversion. |  | ||||||
| type NumError struct { |  | ||||||
| 	Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat) |  | ||||||
| 	Num  string // the input |  | ||||||
| 	Err  error  // the reason the conversion failed (ErrRange, ErrSyntax) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (e *NumError) Error() string { |  | ||||||
| 	return "strconv." + e.Func + ": " + "parsing " + strconv.Quote(e.Num) + ": " + e.Err.Error() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func syntaxError(fn, str string) *NumError { |  | ||||||
| 	return &NumError{fn, str, ErrSyntax} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func rangeError(fn, str string) *NumError { |  | ||||||
| 	return &NumError{fn, str, ErrRange} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const intSize = 32 << uint(^uint(0)>>63) |  | ||||||
|  |  | ||||||
| // IntSize is the size in bits of an int or uint value. |  | ||||||
| const IntSize = intSize |  | ||||||
|  |  | ||||||
| // Return the first number n such that n*base >= 1<<64. |  | ||||||
| func cutoff64(base int) uint64 { |  | ||||||
| 	if base < 2 { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	return (1<<64-1)/uint64(base) + 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ParseUint is like ParseInt but for unsigned numbers, and oeprating on []byte |  | ||||||
| func ParseUint(s []byte, base int, bitSize int) (n uint64, err error) { |  | ||||||
| 	var cutoff, maxVal uint64 |  | ||||||
|  |  | ||||||
| 	if bitSize == 0 { |  | ||||||
| 		bitSize = int(IntSize) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	s0 := s |  | ||||||
| 	switch { |  | ||||||
| 	case len(s) < 1: |  | ||||||
| 		err = ErrSyntax |  | ||||||
| 		goto Error |  | ||||||
|  |  | ||||||
| 	case 2 <= base && base <= 36: |  | ||||||
| 		// valid base; nothing to do |  | ||||||
|  |  | ||||||
| 	case base == 0: |  | ||||||
| 		// Look for octal, hex prefix. |  | ||||||
| 		switch { |  | ||||||
| 		case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'): |  | ||||||
| 			base = 16 |  | ||||||
| 			s = s[2:] |  | ||||||
| 			if len(s) < 1 { |  | ||||||
| 				err = ErrSyntax |  | ||||||
| 				goto Error |  | ||||||
| 			} |  | ||||||
| 		case s[0] == '0': |  | ||||||
| 			base = 8 |  | ||||||
| 		default: |  | ||||||
| 			base = 10 |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		err = errors.New("invalid base " + strconv.Itoa(base)) |  | ||||||
| 		goto Error |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	n = 0 |  | ||||||
| 	cutoff = cutoff64(base) |  | ||||||
| 	maxVal = 1<<uint(bitSize) - 1 |  | ||||||
|  |  | ||||||
| 	for i := 0; i < len(s); i++ { |  | ||||||
| 		var v byte |  | ||||||
| 		d := s[i] |  | ||||||
| 		switch { |  | ||||||
| 		case '0' <= d && d <= '9': |  | ||||||
| 			v = d - '0' |  | ||||||
| 		case 'a' <= d && d <= 'z': |  | ||||||
| 			v = d - 'a' + 10 |  | ||||||
| 		case 'A' <= d && d <= 'Z': |  | ||||||
| 			v = d - 'A' + 10 |  | ||||||
| 		default: |  | ||||||
| 			n = 0 |  | ||||||
| 			err = ErrSyntax |  | ||||||
| 			goto Error |  | ||||||
| 		} |  | ||||||
| 		if int(v) >= base { |  | ||||||
| 			n = 0 |  | ||||||
| 			err = ErrSyntax |  | ||||||
| 			goto Error |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if n >= cutoff { |  | ||||||
| 			// n*base overflows |  | ||||||
| 			n = 1<<64 - 1 |  | ||||||
| 			err = ErrRange |  | ||||||
| 			goto Error |  | ||||||
| 		} |  | ||||||
| 		n *= uint64(base) |  | ||||||
|  |  | ||||||
| 		n1 := n + uint64(v) |  | ||||||
| 		if n1 < n || n1 > maxVal { |  | ||||||
| 			// n+v overflows |  | ||||||
| 			n = 1<<64 - 1 |  | ||||||
| 			err = ErrRange |  | ||||||
| 			goto Error |  | ||||||
| 		} |  | ||||||
| 		n = n1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return n, nil |  | ||||||
|  |  | ||||||
| Error: |  | ||||||
| 	return n, &NumError{"ParseUint", string(s0), err} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ParseInt interprets a string s in the given base (2 to 36) and |  | ||||||
| // returns the corresponding value i.  If base == 0, the base is |  | ||||||
| // implied by the string's prefix: base 16 for "0x", base 8 for |  | ||||||
| // "0", and base 10 otherwise. |  | ||||||
| // |  | ||||||
| // The bitSize argument specifies the integer type |  | ||||||
| // that the result must fit into.  Bit sizes 0, 8, 16, 32, and 64 |  | ||||||
| // correspond to int, int8, int16, int32, and int64. |  | ||||||
| // |  | ||||||
| // The errors that ParseInt returns have concrete type *NumError |  | ||||||
| // and include err.Num = s.  If s is empty or contains invalid |  | ||||||
| // digits, err.Err = ErrSyntax and the returned value is 0; |  | ||||||
| // if the value corresponding to s cannot be represented by a |  | ||||||
| // signed integer of the given size, err.Err = ErrRange and the |  | ||||||
| // returned value is the maximum magnitude integer of the |  | ||||||
| // appropriate bitSize and sign. |  | ||||||
| func ParseInt(s []byte, base int, bitSize int) (i int64, err error) { |  | ||||||
| 	const fnParseInt = "ParseInt" |  | ||||||
|  |  | ||||||
| 	if bitSize == 0 { |  | ||||||
| 		bitSize = int(IntSize) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Empty string bad. |  | ||||||
| 	if len(s) == 0 { |  | ||||||
| 		return 0, syntaxError(fnParseInt, string(s)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Pick off leading sign. |  | ||||||
| 	s0 := s |  | ||||||
| 	neg := false |  | ||||||
| 	if s[0] == '+' { |  | ||||||
| 		s = s[1:] |  | ||||||
| 	} else if s[0] == '-' { |  | ||||||
| 		neg = true |  | ||||||
| 		s = s[1:] |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Convert unsigned and check range. |  | ||||||
| 	var un uint64 |  | ||||||
| 	un, err = ParseUint(s, base, bitSize) |  | ||||||
| 	if err != nil && err.(*NumError).Err != ErrRange { |  | ||||||
| 		err.(*NumError).Func = fnParseInt |  | ||||||
| 		err.(*NumError).Num = string(s0) |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	cutoff := uint64(1 << uint(bitSize-1)) |  | ||||||
| 	if !neg && un >= cutoff { |  | ||||||
| 		return int64(cutoff - 1), rangeError(fnParseInt, string(s0)) |  | ||||||
| 	} |  | ||||||
| 	if neg && un > cutoff { |  | ||||||
| 		return -int64(cutoff), rangeError(fnParseInt, string(s0)) |  | ||||||
| 	} |  | ||||||
| 	n := int64(un) |  | ||||||
| 	if neg { |  | ||||||
| 		n = -n |  | ||||||
| 	} |  | ||||||
| 	return n, nil |  | ||||||
| } |  | ||||||
							
								
								
									
										668
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										668
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,668 +0,0 @@ | |||||||
| // Copyright 2011 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package internal |  | ||||||
|  |  | ||||||
| // An extFloat represents an extended floating-point number, with more |  | ||||||
| // precision than a float64. It does not try to save bits: the |  | ||||||
| // number represented by the structure is mant*(2^exp), with a negative |  | ||||||
| // sign if neg is true. |  | ||||||
| type extFloat struct { |  | ||||||
| 	mant uint64 |  | ||||||
| 	exp  int |  | ||||||
| 	neg  bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Powers of ten taken from double-conversion library. |  | ||||||
| // http://code.google.com/p/double-conversion/ |  | ||||||
| const ( |  | ||||||
| 	firstPowerOfTen = -348 |  | ||||||
| 	stepPowerOfTen  = 8 |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var smallPowersOfTen = [...]extFloat{ |  | ||||||
| 	{1 << 63, -63, false},        // 1 |  | ||||||
| 	{0xa << 60, -60, false},      // 1e1 |  | ||||||
| 	{0x64 << 57, -57, false},     // 1e2 |  | ||||||
| 	{0x3e8 << 54, -54, false},    // 1e3 |  | ||||||
| 	{0x2710 << 50, -50, false},   // 1e4 |  | ||||||
| 	{0x186a0 << 47, -47, false},  // 1e5 |  | ||||||
| 	{0xf4240 << 44, -44, false},  // 1e6 |  | ||||||
| 	{0x989680 << 40, -40, false}, // 1e7 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var powersOfTen = [...]extFloat{ |  | ||||||
| 	{0xfa8fd5a0081c0288, -1220, false}, // 10^-348 |  | ||||||
| 	{0xbaaee17fa23ebf76, -1193, false}, // 10^-340 |  | ||||||
| 	{0x8b16fb203055ac76, -1166, false}, // 10^-332 |  | ||||||
| 	{0xcf42894a5dce35ea, -1140, false}, // 10^-324 |  | ||||||
| 	{0x9a6bb0aa55653b2d, -1113, false}, // 10^-316 |  | ||||||
| 	{0xe61acf033d1a45df, -1087, false}, // 10^-308 |  | ||||||
| 	{0xab70fe17c79ac6ca, -1060, false}, // 10^-300 |  | ||||||
| 	{0xff77b1fcbebcdc4f, -1034, false}, // 10^-292 |  | ||||||
| 	{0xbe5691ef416bd60c, -1007, false}, // 10^-284 |  | ||||||
| 	{0x8dd01fad907ffc3c, -980, false},  // 10^-276 |  | ||||||
| 	{0xd3515c2831559a83, -954, false},  // 10^-268 |  | ||||||
| 	{0x9d71ac8fada6c9b5, -927, false},  // 10^-260 |  | ||||||
| 	{0xea9c227723ee8bcb, -901, false},  // 10^-252 |  | ||||||
| 	{0xaecc49914078536d, -874, false},  // 10^-244 |  | ||||||
| 	{0x823c12795db6ce57, -847, false},  // 10^-236 |  | ||||||
| 	{0xc21094364dfb5637, -821, false},  // 10^-228 |  | ||||||
| 	{0x9096ea6f3848984f, -794, false},  // 10^-220 |  | ||||||
| 	{0xd77485cb25823ac7, -768, false},  // 10^-212 |  | ||||||
| 	{0xa086cfcd97bf97f4, -741, false},  // 10^-204 |  | ||||||
| 	{0xef340a98172aace5, -715, false},  // 10^-196 |  | ||||||
| 	{0xb23867fb2a35b28e, -688, false},  // 10^-188 |  | ||||||
| 	{0x84c8d4dfd2c63f3b, -661, false},  // 10^-180 |  | ||||||
| 	{0xc5dd44271ad3cdba, -635, false},  // 10^-172 |  | ||||||
| 	{0x936b9fcebb25c996, -608, false},  // 10^-164 |  | ||||||
| 	{0xdbac6c247d62a584, -582, false},  // 10^-156 |  | ||||||
| 	{0xa3ab66580d5fdaf6, -555, false},  // 10^-148 |  | ||||||
| 	{0xf3e2f893dec3f126, -529, false},  // 10^-140 |  | ||||||
| 	{0xb5b5ada8aaff80b8, -502, false},  // 10^-132 |  | ||||||
| 	{0x87625f056c7c4a8b, -475, false},  // 10^-124 |  | ||||||
| 	{0xc9bcff6034c13053, -449, false},  // 10^-116 |  | ||||||
| 	{0x964e858c91ba2655, -422, false},  // 10^-108 |  | ||||||
| 	{0xdff9772470297ebd, -396, false},  // 10^-100 |  | ||||||
| 	{0xa6dfbd9fb8e5b88f, -369, false},  // 10^-92 |  | ||||||
| 	{0xf8a95fcf88747d94, -343, false},  // 10^-84 |  | ||||||
| 	{0xb94470938fa89bcf, -316, false},  // 10^-76 |  | ||||||
| 	{0x8a08f0f8bf0f156b, -289, false},  // 10^-68 |  | ||||||
| 	{0xcdb02555653131b6, -263, false},  // 10^-60 |  | ||||||
| 	{0x993fe2c6d07b7fac, -236, false},  // 10^-52 |  | ||||||
| 	{0xe45c10c42a2b3b06, -210, false},  // 10^-44 |  | ||||||
| 	{0xaa242499697392d3, -183, false},  // 10^-36 |  | ||||||
| 	{0xfd87b5f28300ca0e, -157, false},  // 10^-28 |  | ||||||
| 	{0xbce5086492111aeb, -130, false},  // 10^-20 |  | ||||||
| 	{0x8cbccc096f5088cc, -103, false},  // 10^-12 |  | ||||||
| 	{0xd1b71758e219652c, -77, false},   // 10^-4 |  | ||||||
| 	{0x9c40000000000000, -50, false},   // 10^4 |  | ||||||
| 	{0xe8d4a51000000000, -24, false},   // 10^12 |  | ||||||
| 	{0xad78ebc5ac620000, 3, false},     // 10^20 |  | ||||||
| 	{0x813f3978f8940984, 30, false},    // 10^28 |  | ||||||
| 	{0xc097ce7bc90715b3, 56, false},    // 10^36 |  | ||||||
| 	{0x8f7e32ce7bea5c70, 83, false},    // 10^44 |  | ||||||
| 	{0xd5d238a4abe98068, 109, false},   // 10^52 |  | ||||||
| 	{0x9f4f2726179a2245, 136, false},   // 10^60 |  | ||||||
| 	{0xed63a231d4c4fb27, 162, false},   // 10^68 |  | ||||||
| 	{0xb0de65388cc8ada8, 189, false},   // 10^76 |  | ||||||
| 	{0x83c7088e1aab65db, 216, false},   // 10^84 |  | ||||||
| 	{0xc45d1df942711d9a, 242, false},   // 10^92 |  | ||||||
| 	{0x924d692ca61be758, 269, false},   // 10^100 |  | ||||||
| 	{0xda01ee641a708dea, 295, false},   // 10^108 |  | ||||||
| 	{0xa26da3999aef774a, 322, false},   // 10^116 |  | ||||||
| 	{0xf209787bb47d6b85, 348, false},   // 10^124 |  | ||||||
| 	{0xb454e4a179dd1877, 375, false},   // 10^132 |  | ||||||
| 	{0x865b86925b9bc5c2, 402, false},   // 10^140 |  | ||||||
| 	{0xc83553c5c8965d3d, 428, false},   // 10^148 |  | ||||||
| 	{0x952ab45cfa97a0b3, 455, false},   // 10^156 |  | ||||||
| 	{0xde469fbd99a05fe3, 481, false},   // 10^164 |  | ||||||
| 	{0xa59bc234db398c25, 508, false},   // 10^172 |  | ||||||
| 	{0xf6c69a72a3989f5c, 534, false},   // 10^180 |  | ||||||
| 	{0xb7dcbf5354e9bece, 561, false},   // 10^188 |  | ||||||
| 	{0x88fcf317f22241e2, 588, false},   // 10^196 |  | ||||||
| 	{0xcc20ce9bd35c78a5, 614, false},   // 10^204 |  | ||||||
| 	{0x98165af37b2153df, 641, false},   // 10^212 |  | ||||||
| 	{0xe2a0b5dc971f303a, 667, false},   // 10^220 |  | ||||||
| 	{0xa8d9d1535ce3b396, 694, false},   // 10^228 |  | ||||||
| 	{0xfb9b7cd9a4a7443c, 720, false},   // 10^236 |  | ||||||
| 	{0xbb764c4ca7a44410, 747, false},   // 10^244 |  | ||||||
| 	{0x8bab8eefb6409c1a, 774, false},   // 10^252 |  | ||||||
| 	{0xd01fef10a657842c, 800, false},   // 10^260 |  | ||||||
| 	{0x9b10a4e5e9913129, 827, false},   // 10^268 |  | ||||||
| 	{0xe7109bfba19c0c9d, 853, false},   // 10^276 |  | ||||||
| 	{0xac2820d9623bf429, 880, false},   // 10^284 |  | ||||||
| 	{0x80444b5e7aa7cf85, 907, false},   // 10^292 |  | ||||||
| 	{0xbf21e44003acdd2d, 933, false},   // 10^300 |  | ||||||
| 	{0x8e679c2f5e44ff8f, 960, false},   // 10^308 |  | ||||||
| 	{0xd433179d9c8cb841, 986, false},   // 10^316 |  | ||||||
| 	{0x9e19db92b4e31ba9, 1013, false},  // 10^324 |  | ||||||
| 	{0xeb96bf6ebadf77d9, 1039, false},  // 10^332 |  | ||||||
| 	{0xaf87023b9bf0ee6b, 1066, false},  // 10^340 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // floatBits returns the bits of the float64 that best approximates |  | ||||||
| // the extFloat passed as receiver. Overflow is set to true if |  | ||||||
| // the resulting float64 is ±Inf. |  | ||||||
| func (f *extFloat) floatBits(flt *floatInfo) (bits uint64, overflow bool) { |  | ||||||
| 	f.Normalize() |  | ||||||
|  |  | ||||||
| 	exp := f.exp + 63 |  | ||||||
|  |  | ||||||
| 	// Exponent too small. |  | ||||||
| 	if exp < flt.bias+1 { |  | ||||||
| 		n := flt.bias + 1 - exp |  | ||||||
| 		f.mant >>= uint(n) |  | ||||||
| 		exp += n |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Extract 1+flt.mantbits bits from the 64-bit mantissa. |  | ||||||
| 	mant := f.mant >> (63 - flt.mantbits) |  | ||||||
| 	if f.mant&(1<<(62-flt.mantbits)) != 0 { |  | ||||||
| 		// Round up. |  | ||||||
| 		mant += 1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Rounding might have added a bit; shift down. |  | ||||||
| 	if mant == 2<<flt.mantbits { |  | ||||||
| 		mant >>= 1 |  | ||||||
| 		exp++ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Infinities. |  | ||||||
| 	if exp-flt.bias >= 1<<flt.expbits-1 { |  | ||||||
| 		// ±Inf |  | ||||||
| 		mant = 0 |  | ||||||
| 		exp = 1<<flt.expbits - 1 + flt.bias |  | ||||||
| 		overflow = true |  | ||||||
| 	} else if mant&(1<<flt.mantbits) == 0 { |  | ||||||
| 		// Denormalized? |  | ||||||
| 		exp = flt.bias |  | ||||||
| 	} |  | ||||||
| 	// Assemble bits. |  | ||||||
| 	bits = mant & (uint64(1)<<flt.mantbits - 1) |  | ||||||
| 	bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits |  | ||||||
| 	if f.neg { |  | ||||||
| 		bits |= 1 << (flt.mantbits + flt.expbits) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AssignComputeBounds sets f to the floating point value |  | ||||||
| // defined by mant, exp and precision given by flt. It returns |  | ||||||
| // lower, upper such that any number in the closed interval |  | ||||||
| // [lower, upper] is converted back to the same floating point number. |  | ||||||
| func (f *extFloat) AssignComputeBounds(mant uint64, exp int, neg bool, flt *floatInfo) (lower, upper extFloat) { |  | ||||||
| 	f.mant = mant |  | ||||||
| 	f.exp = exp - int(flt.mantbits) |  | ||||||
| 	f.neg = neg |  | ||||||
| 	if f.exp <= 0 && mant == (mant>>uint(-f.exp))<<uint(-f.exp) { |  | ||||||
| 		// An exact integer |  | ||||||
| 		f.mant >>= uint(-f.exp) |  | ||||||
| 		f.exp = 0 |  | ||||||
| 		return *f, *f |  | ||||||
| 	} |  | ||||||
| 	expBiased := exp - flt.bias |  | ||||||
|  |  | ||||||
| 	upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg} |  | ||||||
| 	if mant != 1<<flt.mantbits || expBiased == 1 { |  | ||||||
| 		lower = extFloat{mant: 2*f.mant - 1, exp: f.exp - 1, neg: f.neg} |  | ||||||
| 	} else { |  | ||||||
| 		lower = extFloat{mant: 4*f.mant - 1, exp: f.exp - 2, neg: f.neg} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Normalize normalizes f so that the highest bit of the mantissa is |  | ||||||
| // set, and returns the number by which the mantissa was left-shifted. |  | ||||||
| func (f *extFloat) Normalize() (shift uint) { |  | ||||||
| 	mant, exp := f.mant, f.exp |  | ||||||
| 	if mant == 0 { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-32) == 0 { |  | ||||||
| 		mant <<= 32 |  | ||||||
| 		exp -= 32 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-16) == 0 { |  | ||||||
| 		mant <<= 16 |  | ||||||
| 		exp -= 16 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-8) == 0 { |  | ||||||
| 		mant <<= 8 |  | ||||||
| 		exp -= 8 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-4) == 0 { |  | ||||||
| 		mant <<= 4 |  | ||||||
| 		exp -= 4 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-2) == 0 { |  | ||||||
| 		mant <<= 2 |  | ||||||
| 		exp -= 2 |  | ||||||
| 	} |  | ||||||
| 	if mant>>(64-1) == 0 { |  | ||||||
| 		mant <<= 1 |  | ||||||
| 		exp -= 1 |  | ||||||
| 	} |  | ||||||
| 	shift = uint(f.exp - exp) |  | ||||||
| 	f.mant, f.exp = mant, exp |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Multiply sets f to the product f*g: the result is correctly rounded, |  | ||||||
| // but not normalized. |  | ||||||
| func (f *extFloat) Multiply(g extFloat) { |  | ||||||
| 	fhi, flo := f.mant>>32, uint64(uint32(f.mant)) |  | ||||||
| 	ghi, glo := g.mant>>32, uint64(uint32(g.mant)) |  | ||||||
|  |  | ||||||
| 	// Cross products. |  | ||||||
| 	cross1 := fhi * glo |  | ||||||
| 	cross2 := flo * ghi |  | ||||||
|  |  | ||||||
| 	// f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo |  | ||||||
| 	f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32) |  | ||||||
| 	rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32) |  | ||||||
| 	// Round up. |  | ||||||
| 	rem += (1 << 31) |  | ||||||
|  |  | ||||||
| 	f.mant += (rem >> 32) |  | ||||||
| 	f.exp = f.exp + g.exp + 64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var uint64pow10 = [...]uint64{ |  | ||||||
| 	1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, |  | ||||||
| 	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AssignDecimal sets f to an approximate value mantissa*10^exp. It |  | ||||||
| // returns true if the value represented by f is guaranteed to be the |  | ||||||
| // best approximation of d after being rounded to a float64 or |  | ||||||
| // float32 depending on flt. |  | ||||||
| func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) { |  | ||||||
| 	const uint64digits = 19 |  | ||||||
| 	const errorscale = 8 |  | ||||||
| 	errors := 0 // An upper bound for error, computed in errorscale*ulp. |  | ||||||
| 	if trunc { |  | ||||||
| 		// the decimal number was truncated. |  | ||||||
| 		errors += errorscale / 2 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	f.mant = mantissa |  | ||||||
| 	f.exp = 0 |  | ||||||
| 	f.neg = neg |  | ||||||
|  |  | ||||||
| 	// Multiply by powers of ten. |  | ||||||
| 	i := (exp10 - firstPowerOfTen) / stepPowerOfTen |  | ||||||
| 	if exp10 < firstPowerOfTen || i >= len(powersOfTen) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen |  | ||||||
|  |  | ||||||
| 	// We multiply by exp%step |  | ||||||
| 	if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] { |  | ||||||
| 		// We can multiply the mantissa exactly. |  | ||||||
| 		f.mant *= uint64pow10[adjExp] |  | ||||||
| 		f.Normalize() |  | ||||||
| 	} else { |  | ||||||
| 		f.Normalize() |  | ||||||
| 		f.Multiply(smallPowersOfTen[adjExp]) |  | ||||||
| 		errors += errorscale / 2 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// We multiply by 10 to the exp - exp%step. |  | ||||||
| 	f.Multiply(powersOfTen[i]) |  | ||||||
| 	if errors > 0 { |  | ||||||
| 		errors += 1 |  | ||||||
| 	} |  | ||||||
| 	errors += errorscale / 2 |  | ||||||
|  |  | ||||||
| 	// Normalize |  | ||||||
| 	shift := f.Normalize() |  | ||||||
| 	errors <<= shift |  | ||||||
|  |  | ||||||
| 	// Now f is a good approximation of the decimal. |  | ||||||
| 	// Check whether the error is too large: that is, if the mantissa |  | ||||||
| 	// is perturbated by the error, the resulting float64 will change. |  | ||||||
| 	// The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits. |  | ||||||
| 	// |  | ||||||
| 	// In many cases the approximation will be good enough. |  | ||||||
| 	denormalExp := flt.bias - 63 |  | ||||||
| 	var extrabits uint |  | ||||||
| 	if f.exp <= denormalExp { |  | ||||||
| 		// f.mant * 2^f.exp is smaller than 2^(flt.bias+1). |  | ||||||
| 		extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp)) |  | ||||||
| 	} else { |  | ||||||
| 		extrabits = uint(63 - flt.mantbits) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	halfway := uint64(1) << (extrabits - 1) |  | ||||||
| 	mant_extra := f.mant & (1<<extrabits - 1) |  | ||||||
|  |  | ||||||
| 	// Do a signed comparison here! If the error estimate could make |  | ||||||
| 	// the mantissa round differently for the conversion to double, |  | ||||||
| 	// then we can't give a definite answer. |  | ||||||
| 	if int64(halfway)-int64(errors) < int64(mant_extra) && |  | ||||||
| 		int64(mant_extra) < int64(halfway)+int64(errors) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Frexp10 is an analogue of math.Frexp for decimal powers. It scales |  | ||||||
| // f by an approximate power of ten 10^-exp, and returns exp10, so |  | ||||||
| // that f*10^exp10 has the same value as the old f, up to an ulp, |  | ||||||
| // as well as the index of 10^-exp in the powersOfTen table. |  | ||||||
| func (f *extFloat) frexp10() (exp10, index int) { |  | ||||||
| 	// The constants expMin and expMax constrain the final value of the |  | ||||||
| 	// binary exponent of f. We want a small integral part in the result |  | ||||||
| 	// because finding digits of an integer requires divisions, whereas |  | ||||||
| 	// digits of the fractional part can be found by repeatedly multiplying |  | ||||||
| 	// by 10. |  | ||||||
| 	const expMin = -60 |  | ||||||
| 	const expMax = -32 |  | ||||||
| 	// Find power of ten such that x * 10^n has a binary exponent |  | ||||||
| 	// between expMin and expMax. |  | ||||||
| 	approxExp10 := ((expMin+expMax)/2 - f.exp) * 28 / 93 // log(10)/log(2) is close to 93/28. |  | ||||||
| 	i := (approxExp10 - firstPowerOfTen) / stepPowerOfTen |  | ||||||
| Loop: |  | ||||||
| 	for { |  | ||||||
| 		exp := f.exp + powersOfTen[i].exp + 64 |  | ||||||
| 		switch { |  | ||||||
| 		case exp < expMin: |  | ||||||
| 			i++ |  | ||||||
| 		case exp > expMax: |  | ||||||
| 			i-- |  | ||||||
| 		default: |  | ||||||
| 			break Loop |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	// Apply the desired decimal shift on f. It will have exponent |  | ||||||
| 	// in the desired range. This is multiplication by 10^-exp10. |  | ||||||
| 	f.Multiply(powersOfTen[i]) |  | ||||||
|  |  | ||||||
| 	return -(firstPowerOfTen + i*stepPowerOfTen), i |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // frexp10Many applies a common shift by a power of ten to a, b, c. |  | ||||||
| func frexp10Many(a, b, c *extFloat) (exp10 int) { |  | ||||||
| 	exp10, i := c.frexp10() |  | ||||||
| 	a.Multiply(powersOfTen[i]) |  | ||||||
| 	b.Multiply(powersOfTen[i]) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // FixedDecimal stores in d the first n significant digits |  | ||||||
| // of the decimal representation of f. It returns false |  | ||||||
| // if it cannot be sure of the answer. |  | ||||||
| func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool { |  | ||||||
| 	if f.mant == 0 { |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		d.dp = 0 |  | ||||||
| 		d.neg = f.neg |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if n == 0 { |  | ||||||
| 		panic("strconv: internal error: extFloat.FixedDecimal called with n == 0") |  | ||||||
| 	} |  | ||||||
| 	// Multiply by an appropriate power of ten to have a reasonable |  | ||||||
| 	// number to process. |  | ||||||
| 	f.Normalize() |  | ||||||
| 	exp10, _ := f.frexp10() |  | ||||||
|  |  | ||||||
| 	shift := uint(-f.exp) |  | ||||||
| 	integer := uint32(f.mant >> shift) |  | ||||||
| 	fraction := f.mant - (uint64(integer) << shift) |  | ||||||
| 	ε := uint64(1) // ε is the uncertainty we have on the mantissa of f. |  | ||||||
|  |  | ||||||
| 	// Write exactly n digits to d. |  | ||||||
| 	needed := n        // how many digits are left to write. |  | ||||||
| 	integerDigits := 0 // the number of decimal digits of integer. |  | ||||||
| 	pow10 := uint64(1) // the power of ten by which f was scaled. |  | ||||||
| 	for i, pow := 0, uint64(1); i < 20; i++ { |  | ||||||
| 		if pow > uint64(integer) { |  | ||||||
| 			integerDigits = i |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		pow *= 10 |  | ||||||
| 	} |  | ||||||
| 	rest := integer |  | ||||||
| 	if integerDigits > needed { |  | ||||||
| 		// the integral part is already large, trim the last digits. |  | ||||||
| 		pow10 = uint64pow10[integerDigits-needed] |  | ||||||
| 		integer /= uint32(pow10) |  | ||||||
| 		rest -= integer * uint32(pow10) |  | ||||||
| 	} else { |  | ||||||
| 		rest = 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Write the digits of integer: the digits of rest are omitted. |  | ||||||
| 	var buf [32]byte |  | ||||||
| 	pos := len(buf) |  | ||||||
| 	for v := integer; v > 0; { |  | ||||||
| 		v1 := v / 10 |  | ||||||
| 		v -= 10 * v1 |  | ||||||
| 		pos-- |  | ||||||
| 		buf[pos] = byte(v + '0') |  | ||||||
| 		v = v1 |  | ||||||
| 	} |  | ||||||
| 	for i := pos; i < len(buf); i++ { |  | ||||||
| 		d.d[i-pos] = buf[i] |  | ||||||
| 	} |  | ||||||
| 	nd := len(buf) - pos |  | ||||||
| 	d.nd = nd |  | ||||||
| 	d.dp = integerDigits + exp10 |  | ||||||
| 	needed -= nd |  | ||||||
|  |  | ||||||
| 	if needed > 0 { |  | ||||||
| 		if rest != 0 || pow10 != 1 { |  | ||||||
| 			panic("strconv: internal error, rest != 0 but needed > 0") |  | ||||||
| 		} |  | ||||||
| 		// Emit digits for the fractional part. Each time, 10*fraction |  | ||||||
| 		// fits in a uint64 without overflow. |  | ||||||
| 		for needed > 0 { |  | ||||||
| 			fraction *= 10 |  | ||||||
| 			ε *= 10 // the uncertainty scales as we multiply by ten. |  | ||||||
| 			if 2*ε > 1<<shift { |  | ||||||
| 				// the error is so large it could modify which digit to write, abort. |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 			digit := fraction >> shift |  | ||||||
| 			d.d[nd] = byte(digit + '0') |  | ||||||
| 			fraction -= digit << shift |  | ||||||
| 			nd++ |  | ||||||
| 			needed-- |  | ||||||
| 		} |  | ||||||
| 		d.nd = nd |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// We have written a truncation of f (a numerator / 10^d.dp). The remaining part |  | ||||||
| 	// can be interpreted as a small number (< 1) to be added to the last digit of the |  | ||||||
| 	// numerator. |  | ||||||
| 	// |  | ||||||
| 	// If rest > 0, the amount is: |  | ||||||
| 	//    (rest<<shift | fraction) / (pow10 << shift) |  | ||||||
| 	//    fraction being known with a ±ε uncertainty. |  | ||||||
| 	//    The fact that n > 0 guarantees that pow10 << shift does not overflow a uint64. |  | ||||||
| 	// |  | ||||||
| 	// If rest = 0, pow10 == 1 and the amount is |  | ||||||
| 	//    fraction / (1 << shift) |  | ||||||
| 	//    fraction being known with a ±ε uncertainty. |  | ||||||
| 	// |  | ||||||
| 	// We pass this information to the rounding routine for adjustment. |  | ||||||
|  |  | ||||||
| 	ok := adjustLastDigitFixed(d, uint64(rest)<<shift|fraction, pow10, shift, ε) |  | ||||||
| 	if !ok { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	// Trim trailing zeros. |  | ||||||
| 	for i := d.nd - 1; i >= 0; i-- { |  | ||||||
| 		if d.d[i] != '0' { |  | ||||||
| 			d.nd = i + 1 |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // adjustLastDigitFixed assumes d contains the representation of the integral part |  | ||||||
| // of some number, whose fractional part is num / (den << shift). The numerator |  | ||||||
| // num is only known up to an uncertainty of size ε, assumed to be less than |  | ||||||
| // (den << shift)/2. |  | ||||||
| // |  | ||||||
| // It will increase the last digit by one to account for correct rounding, typically |  | ||||||
| // when the fractional part is greater than 1/2, and will return false if ε is such |  | ||||||
| // that no correct answer can be given. |  | ||||||
| func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool { |  | ||||||
| 	if num > den<<shift { |  | ||||||
| 		panic("strconv: num > den<<shift in adjustLastDigitFixed") |  | ||||||
| 	} |  | ||||||
| 	if 2*ε > den<<shift { |  | ||||||
| 		panic("strconv: ε > (den<<shift)/2") |  | ||||||
| 	} |  | ||||||
| 	if 2*(num+ε) < den<<shift { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if 2*(num-ε) > den<<shift { |  | ||||||
| 		// increment d by 1. |  | ||||||
| 		i := d.nd - 1 |  | ||||||
| 		for ; i >= 0; i-- { |  | ||||||
| 			if d.d[i] == '9' { |  | ||||||
| 				d.nd-- |  | ||||||
| 			} else { |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if i < 0 { |  | ||||||
| 			d.d[0] = '1' |  | ||||||
| 			d.nd = 1 |  | ||||||
| 			d.dp++ |  | ||||||
| 		} else { |  | ||||||
| 			d.d[i]++ |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ShortestDecimal stores in d the shortest decimal representation of f |  | ||||||
| // which belongs to the open interval (lower, upper), where f is supposed |  | ||||||
| // to lie. It returns false whenever the result is unsure. The implementation |  | ||||||
| // uses the Grisu3 algorithm. |  | ||||||
| func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool { |  | ||||||
| 	if f.mant == 0 { |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		d.dp = 0 |  | ||||||
| 		d.neg = f.neg |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if f.exp == 0 && *lower == *f && *lower == *upper { |  | ||||||
| 		// an exact integer. |  | ||||||
| 		var buf [24]byte |  | ||||||
| 		n := len(buf) - 1 |  | ||||||
| 		for v := f.mant; v > 0; { |  | ||||||
| 			v1 := v / 10 |  | ||||||
| 			v -= 10 * v1 |  | ||||||
| 			buf[n] = byte(v + '0') |  | ||||||
| 			n-- |  | ||||||
| 			v = v1 |  | ||||||
| 		} |  | ||||||
| 		nd := len(buf) - n - 1 |  | ||||||
| 		for i := 0; i < nd; i++ { |  | ||||||
| 			d.d[i] = buf[n+1+i] |  | ||||||
| 		} |  | ||||||
| 		d.nd, d.dp = nd, nd |  | ||||||
| 		for d.nd > 0 && d.d[d.nd-1] == '0' { |  | ||||||
| 			d.nd-- |  | ||||||
| 		} |  | ||||||
| 		if d.nd == 0 { |  | ||||||
| 			d.dp = 0 |  | ||||||
| 		} |  | ||||||
| 		d.neg = f.neg |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	upper.Normalize() |  | ||||||
| 	// Uniformize exponents. |  | ||||||
| 	if f.exp > upper.exp { |  | ||||||
| 		f.mant <<= uint(f.exp - upper.exp) |  | ||||||
| 		f.exp = upper.exp |  | ||||||
| 	} |  | ||||||
| 	if lower.exp > upper.exp { |  | ||||||
| 		lower.mant <<= uint(lower.exp - upper.exp) |  | ||||||
| 		lower.exp = upper.exp |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	exp10 := frexp10Many(lower, f, upper) |  | ||||||
| 	// Take a safety margin due to rounding in frexp10Many, but we lose precision. |  | ||||||
| 	upper.mant++ |  | ||||||
| 	lower.mant-- |  | ||||||
|  |  | ||||||
| 	// The shortest representation of f is either rounded up or down, but |  | ||||||
| 	// in any case, it is a truncation of upper. |  | ||||||
| 	shift := uint(-upper.exp) |  | ||||||
| 	integer := uint32(upper.mant >> shift) |  | ||||||
| 	fraction := upper.mant - (uint64(integer) << shift) |  | ||||||
|  |  | ||||||
| 	// How far we can go down from upper until the result is wrong. |  | ||||||
| 	allowance := upper.mant - lower.mant |  | ||||||
| 	// How far we should go to get a very precise result. |  | ||||||
| 	targetDiff := upper.mant - f.mant |  | ||||||
|  |  | ||||||
| 	// Count integral digits: there are at most 10. |  | ||||||
| 	var integerDigits int |  | ||||||
| 	for i, pow := 0, uint64(1); i < 20; i++ { |  | ||||||
| 		if pow > uint64(integer) { |  | ||||||
| 			integerDigits = i |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		pow *= 10 |  | ||||||
| 	} |  | ||||||
| 	for i := 0; i < integerDigits; i++ { |  | ||||||
| 		pow := uint64pow10[integerDigits-i-1] |  | ||||||
| 		digit := integer / uint32(pow) |  | ||||||
| 		d.d[i] = byte(digit + '0') |  | ||||||
| 		integer -= digit * uint32(pow) |  | ||||||
| 		// evaluate whether we should stop. |  | ||||||
| 		if currentDiff := uint64(integer)<<shift + fraction; currentDiff < allowance { |  | ||||||
| 			d.nd = i + 1 |  | ||||||
| 			d.dp = integerDigits + exp10 |  | ||||||
| 			d.neg = f.neg |  | ||||||
| 			// Sometimes allowance is so large the last digit might need to be |  | ||||||
| 			// decremented to get closer to f. |  | ||||||
| 			return adjustLastDigit(d, currentDiff, targetDiff, allowance, pow<<shift, 2) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	d.nd = integerDigits |  | ||||||
| 	d.dp = d.nd + exp10 |  | ||||||
| 	d.neg = f.neg |  | ||||||
|  |  | ||||||
| 	// Compute digits of the fractional part. At each step fraction does not |  | ||||||
| 	// overflow. The choice of minExp implies that fraction is less than 2^60. |  | ||||||
| 	var digit int |  | ||||||
| 	multiplier := uint64(1) |  | ||||||
| 	for { |  | ||||||
| 		fraction *= 10 |  | ||||||
| 		multiplier *= 10 |  | ||||||
| 		digit = int(fraction >> shift) |  | ||||||
| 		d.d[d.nd] = byte(digit + '0') |  | ||||||
| 		d.nd++ |  | ||||||
| 		fraction -= uint64(digit) << shift |  | ||||||
| 		if fraction < allowance*multiplier { |  | ||||||
| 			// We are in the admissible range. Note that if allowance is about to |  | ||||||
| 			// overflow, that is, allowance > 2^64/10, the condition is automatically |  | ||||||
| 			// true due to the limited range of fraction. |  | ||||||
| 			return adjustLastDigit(d, |  | ||||||
| 				fraction, targetDiff*multiplier, allowance*multiplier, |  | ||||||
| 				1<<shift, multiplier*2) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // adjustLastDigit modifies d = x-currentDiff*ε, to get closest to |  | ||||||
| // d = x-targetDiff*ε, without becoming smaller than x-maxDiff*ε. |  | ||||||
| // It assumes that a decimal digit is worth ulpDecimal*ε, and that |  | ||||||
| // all data is known with a error estimate of ulpBinary*ε. |  | ||||||
| func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool { |  | ||||||
| 	if ulpDecimal < 2*ulpBinary { |  | ||||||
| 		// Approximation is too wide. |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for currentDiff+ulpDecimal/2+ulpBinary < targetDiff { |  | ||||||
| 		d.d[d.nd-1]-- |  | ||||||
| 		currentDiff += ulpDecimal |  | ||||||
| 	} |  | ||||||
| 	if currentDiff+ulpDecimal <= targetDiff+ulpDecimal/2+ulpBinary { |  | ||||||
| 		// we have two choices, and don't know what to do. |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if currentDiff < ulpBinary || currentDiff > maxDiff-ulpBinary { |  | ||||||
| 		// we went too far |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if d.nd == 1 && d.d[0] == '0' { |  | ||||||
| 		// the number has actually reached zero. |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		d.dp = 0 |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
							
								
								
									
										475
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/ftoa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										475
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/ftoa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,475 +0,0 @@ | |||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| // Binary to decimal floating point conversion. |  | ||||||
| // Algorithm: |  | ||||||
| //   1) store mantissa in multiprecision decimal |  | ||||||
| //   2) shift decimal by exponent |  | ||||||
| //   3) read digits out & format |  | ||||||
|  |  | ||||||
| package internal |  | ||||||
|  |  | ||||||
| import "math" |  | ||||||
|  |  | ||||||
| // TODO: move elsewhere? |  | ||||||
| type floatInfo struct { |  | ||||||
| 	mantbits uint |  | ||||||
| 	expbits  uint |  | ||||||
| 	bias     int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var float32info = floatInfo{23, 8, -127} |  | ||||||
| var float64info = floatInfo{52, 11, -1023} |  | ||||||
|  |  | ||||||
| // FormatFloat converts the floating-point number f to a string, |  | ||||||
| // according to the format fmt and precision prec.  It rounds the |  | ||||||
| // result assuming that the original was obtained from a floating-point |  | ||||||
| // value of bitSize bits (32 for float32, 64 for float64). |  | ||||||
| // |  | ||||||
| // The format fmt is one of |  | ||||||
| // 'b' (-ddddp±ddd, a binary exponent), |  | ||||||
| // 'e' (-d.dddde±dd, a decimal exponent), |  | ||||||
| // 'E' (-d.ddddE±dd, a decimal exponent), |  | ||||||
| // 'f' (-ddd.dddd, no exponent), |  | ||||||
| // 'g' ('e' for large exponents, 'f' otherwise), or |  | ||||||
| // 'G' ('E' for large exponents, 'f' otherwise). |  | ||||||
| // |  | ||||||
| // The precision prec controls the number of digits |  | ||||||
| // (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats. |  | ||||||
| // For 'e', 'E', and 'f' it is the number of digits after the decimal point. |  | ||||||
| // For 'g' and 'G' it is the total number of digits. |  | ||||||
| // The special precision -1 uses the smallest number of digits |  | ||||||
| // necessary such that ParseFloat will return f exactly. |  | ||||||
| func formatFloat(f float64, fmt byte, prec, bitSize int) string { |  | ||||||
| 	return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AppendFloat appends the string form of the floating-point number f, |  | ||||||
| // as generated by FormatFloat, to dst and returns the extended buffer. |  | ||||||
| func appendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte { |  | ||||||
| 	return genericFtoa(dst, f, fmt, prec, bitSize) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte { |  | ||||||
| 	var bits uint64 |  | ||||||
| 	var flt *floatInfo |  | ||||||
| 	switch bitSize { |  | ||||||
| 	case 32: |  | ||||||
| 		bits = uint64(math.Float32bits(float32(val))) |  | ||||||
| 		flt = &float32info |  | ||||||
| 	case 64: |  | ||||||
| 		bits = math.Float64bits(val) |  | ||||||
| 		flt = &float64info |  | ||||||
| 	default: |  | ||||||
| 		panic("strconv: illegal AppendFloat/FormatFloat bitSize") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	neg := bits>>(flt.expbits+flt.mantbits) != 0 |  | ||||||
| 	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1) |  | ||||||
| 	mant := bits & (uint64(1)<<flt.mantbits - 1) |  | ||||||
|  |  | ||||||
| 	switch exp { |  | ||||||
| 	case 1<<flt.expbits - 1: |  | ||||||
| 		// Inf, NaN |  | ||||||
| 		var s string |  | ||||||
| 		switch { |  | ||||||
| 		case mant != 0: |  | ||||||
| 			s = "NaN" |  | ||||||
| 		case neg: |  | ||||||
| 			s = "-Inf" |  | ||||||
| 		default: |  | ||||||
| 			s = "+Inf" |  | ||||||
| 		} |  | ||||||
| 		return append(dst, s...) |  | ||||||
|  |  | ||||||
| 	case 0: |  | ||||||
| 		// denormalized |  | ||||||
| 		exp++ |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		// add implicit top bit |  | ||||||
| 		mant |= uint64(1) << flt.mantbits |  | ||||||
| 	} |  | ||||||
| 	exp += flt.bias |  | ||||||
|  |  | ||||||
| 	// Pick off easy binary format. |  | ||||||
| 	if fmt == 'b' { |  | ||||||
| 		return fmtB(dst, neg, mant, exp, flt) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !optimize { |  | ||||||
| 		return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var digs decimalSlice |  | ||||||
| 	ok := false |  | ||||||
| 	// Negative precision means "only as much as needed to be exact." |  | ||||||
| 	shortest := prec < 0 |  | ||||||
| 	if shortest { |  | ||||||
| 		// Try Grisu3 algorithm. |  | ||||||
| 		f := new(extFloat) |  | ||||||
| 		lower, upper := f.AssignComputeBounds(mant, exp, neg, flt) |  | ||||||
| 		var buf [32]byte |  | ||||||
| 		digs.d = buf[:] |  | ||||||
| 		ok = f.ShortestDecimal(&digs, &lower, &upper) |  | ||||||
| 		if !ok { |  | ||||||
| 			return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) |  | ||||||
| 		} |  | ||||||
| 		// Precision for shortest representation mode. |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			prec = digs.nd - 1 |  | ||||||
| 		case 'f': |  | ||||||
| 			prec = max(digs.nd-digs.dp, 0) |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			prec = digs.nd |  | ||||||
| 		} |  | ||||||
| 	} else if fmt != 'f' { |  | ||||||
| 		// Fixed number of digits. |  | ||||||
| 		digits := prec |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			digits++ |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			if prec == 0 { |  | ||||||
| 				prec = 1 |  | ||||||
| 			} |  | ||||||
| 			digits = prec |  | ||||||
| 		} |  | ||||||
| 		if digits <= 15 { |  | ||||||
| 			// try fast algorithm when the number of digits is reasonable. |  | ||||||
| 			var buf [24]byte |  | ||||||
| 			digs.d = buf[:] |  | ||||||
| 			f := extFloat{mant, exp - int(flt.mantbits), neg} |  | ||||||
| 			ok = f.FixedDecimal(&digs, digits) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if !ok { |  | ||||||
| 		return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) |  | ||||||
| 	} |  | ||||||
| 	return formatDigits(dst, shortest, neg, digs, prec, fmt) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // bigFtoa uses multiprecision computations to format a float. |  | ||||||
| func bigFtoa(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte { |  | ||||||
| 	d := new(decimal) |  | ||||||
| 	d.Assign(mant) |  | ||||||
| 	d.Shift(exp - int(flt.mantbits)) |  | ||||||
| 	var digs decimalSlice |  | ||||||
| 	shortest := prec < 0 |  | ||||||
| 	if shortest { |  | ||||||
| 		roundShortest(d, mant, exp, flt) |  | ||||||
| 		digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp} |  | ||||||
| 		// Precision for shortest representation mode. |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			prec = digs.nd - 1 |  | ||||||
| 		case 'f': |  | ||||||
| 			prec = max(digs.nd-digs.dp, 0) |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			prec = digs.nd |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		// Round appropriately. |  | ||||||
| 		switch fmt { |  | ||||||
| 		case 'e', 'E': |  | ||||||
| 			d.Round(prec + 1) |  | ||||||
| 		case 'f': |  | ||||||
| 			d.Round(d.dp + prec) |  | ||||||
| 		case 'g', 'G': |  | ||||||
| 			if prec == 0 { |  | ||||||
| 				prec = 1 |  | ||||||
| 			} |  | ||||||
| 			d.Round(prec) |  | ||||||
| 		} |  | ||||||
| 		digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp} |  | ||||||
| 	} |  | ||||||
| 	return formatDigits(dst, shortest, neg, digs, prec, fmt) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte { |  | ||||||
| 	switch fmt { |  | ||||||
| 	case 'e', 'E': |  | ||||||
| 		return fmtE(dst, neg, digs, prec, fmt) |  | ||||||
| 	case 'f': |  | ||||||
| 		return fmtF(dst, neg, digs, prec) |  | ||||||
| 	case 'g', 'G': |  | ||||||
| 		// trailing fractional zeros in 'e' form will be trimmed. |  | ||||||
| 		eprec := prec |  | ||||||
| 		if eprec > digs.nd && digs.nd >= digs.dp { |  | ||||||
| 			eprec = digs.nd |  | ||||||
| 		} |  | ||||||
| 		// %e is used if the exponent from the conversion |  | ||||||
| 		// is less than -4 or greater than or equal to the precision. |  | ||||||
| 		// if precision was the shortest possible, use precision 6 for this decision. |  | ||||||
| 		if shortest { |  | ||||||
| 			eprec = 6 |  | ||||||
| 		} |  | ||||||
| 		exp := digs.dp - 1 |  | ||||||
| 		if exp < -4 || exp >= eprec { |  | ||||||
| 			if prec > digs.nd { |  | ||||||
| 				prec = digs.nd |  | ||||||
| 			} |  | ||||||
| 			return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g') |  | ||||||
| 		} |  | ||||||
| 		if prec > digs.dp { |  | ||||||
| 			prec = digs.nd |  | ||||||
| 		} |  | ||||||
| 		return fmtF(dst, neg, digs, max(prec-digs.dp, 0)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// unknown format |  | ||||||
| 	return append(dst, '%', fmt) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Round d (= mant * 2^exp) to the shortest number of digits |  | ||||||
| // that will let the original floating point value be precisely |  | ||||||
| // reconstructed.  Size is original floating point size (64 or 32). |  | ||||||
| func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { |  | ||||||
| 	// If mantissa is zero, the number is zero; stop now. |  | ||||||
| 	if mant == 0 { |  | ||||||
| 		d.nd = 0 |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Compute upper and lower such that any decimal number |  | ||||||
| 	// between upper and lower (possibly inclusive) |  | ||||||
| 	// will round to the original floating point number. |  | ||||||
|  |  | ||||||
| 	// We may see at once that the number is already shortest. |  | ||||||
| 	// |  | ||||||
| 	// Suppose d is not denormal, so that 2^exp <= d < 10^dp. |  | ||||||
| 	// The closest shorter number is at least 10^(dp-nd) away. |  | ||||||
| 	// The lower/upper bounds computed below are at distance |  | ||||||
| 	// at most 2^(exp-mantbits). |  | ||||||
| 	// |  | ||||||
| 	// So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits), |  | ||||||
| 	// or equivalently log2(10)*(dp-nd) > exp-mantbits. |  | ||||||
| 	// It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32). |  | ||||||
| 	minexp := flt.bias + 1 // minimum possible exponent |  | ||||||
| 	if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) { |  | ||||||
| 		// The number is already shortest. |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// d = mant << (exp - mantbits) |  | ||||||
| 	// Next highest floating point number is mant+1 << exp-mantbits. |  | ||||||
| 	// Our upper bound is halfway between, mant*2+1 << exp-mantbits-1. |  | ||||||
| 	upper := new(decimal) |  | ||||||
| 	upper.Assign(mant*2 + 1) |  | ||||||
| 	upper.Shift(exp - int(flt.mantbits) - 1) |  | ||||||
|  |  | ||||||
| 	// d = mant << (exp - mantbits) |  | ||||||
| 	// Next lowest floating point number is mant-1 << exp-mantbits, |  | ||||||
| 	// unless mant-1 drops the significant bit and exp is not the minimum exp, |  | ||||||
| 	// in which case the next lowest is mant*2-1 << exp-mantbits-1. |  | ||||||
| 	// Either way, call it mantlo << explo-mantbits. |  | ||||||
| 	// Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1. |  | ||||||
| 	var mantlo uint64 |  | ||||||
| 	var explo int |  | ||||||
| 	if mant > 1<<flt.mantbits || exp == minexp { |  | ||||||
| 		mantlo = mant - 1 |  | ||||||
| 		explo = exp |  | ||||||
| 	} else { |  | ||||||
| 		mantlo = mant*2 - 1 |  | ||||||
| 		explo = exp - 1 |  | ||||||
| 	} |  | ||||||
| 	lower := new(decimal) |  | ||||||
| 	lower.Assign(mantlo*2 + 1) |  | ||||||
| 	lower.Shift(explo - int(flt.mantbits) - 1) |  | ||||||
|  |  | ||||||
| 	// The upper and lower bounds are possible outputs only if |  | ||||||
| 	// the original mantissa is even, so that IEEE round-to-even |  | ||||||
| 	// would round to the original mantissa and not the neighbors. |  | ||||||
| 	inclusive := mant%2 == 0 |  | ||||||
|  |  | ||||||
| 	// Now we can figure out the minimum number of digits required. |  | ||||||
| 	// Walk along until d has distinguished itself from upper and lower. |  | ||||||
| 	for i := 0; i < d.nd; i++ { |  | ||||||
| 		var l, m, u byte // lower, middle, upper digits |  | ||||||
| 		if i < lower.nd { |  | ||||||
| 			l = lower.d[i] |  | ||||||
| 		} else { |  | ||||||
| 			l = '0' |  | ||||||
| 		} |  | ||||||
| 		m = d.d[i] |  | ||||||
| 		if i < upper.nd { |  | ||||||
| 			u = upper.d[i] |  | ||||||
| 		} else { |  | ||||||
| 			u = '0' |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Okay to round down (truncate) if lower has a different digit |  | ||||||
| 		// or if lower is inclusive and is exactly the result of rounding down. |  | ||||||
| 		okdown := l != m || (inclusive && l == m && i+1 == lower.nd) |  | ||||||
|  |  | ||||||
| 		// Okay to round up if upper has a different digit and |  | ||||||
| 		// either upper is inclusive or upper is bigger than the result of rounding up. |  | ||||||
| 		okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd) |  | ||||||
|  |  | ||||||
| 		// If it's okay to do either, then round to the nearest one. |  | ||||||
| 		// If it's okay to do only one, do it. |  | ||||||
| 		switch { |  | ||||||
| 		case okdown && okup: |  | ||||||
| 			d.Round(i + 1) |  | ||||||
| 			return |  | ||||||
| 		case okdown: |  | ||||||
| 			d.RoundDown(i + 1) |  | ||||||
| 			return |  | ||||||
| 		case okup: |  | ||||||
| 			d.RoundUp(i + 1) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type decimalSlice struct { |  | ||||||
| 	d      []byte |  | ||||||
| 	nd, dp int |  | ||||||
| 	neg    bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // %e: -d.ddddde±dd |  | ||||||
| func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte { |  | ||||||
| 	// sign |  | ||||||
| 	if neg { |  | ||||||
| 		dst = append(dst, '-') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// first digit |  | ||||||
| 	ch := byte('0') |  | ||||||
| 	if d.nd != 0 { |  | ||||||
| 		ch = d.d[0] |  | ||||||
| 	} |  | ||||||
| 	dst = append(dst, ch) |  | ||||||
|  |  | ||||||
| 	// .moredigits |  | ||||||
| 	if prec > 0 { |  | ||||||
| 		dst = append(dst, '.') |  | ||||||
| 		i := 1 |  | ||||||
| 		m := d.nd + prec + 1 - max(d.nd, prec+1) |  | ||||||
| 		for i < m { |  | ||||||
| 			dst = append(dst, d.d[i]) |  | ||||||
| 			i++ |  | ||||||
| 		} |  | ||||||
| 		for i <= prec { |  | ||||||
| 			dst = append(dst, '0') |  | ||||||
| 			i++ |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// e± |  | ||||||
| 	dst = append(dst, fmt) |  | ||||||
| 	exp := d.dp - 1 |  | ||||||
| 	if d.nd == 0 { // special case: 0 has exponent 0 |  | ||||||
| 		exp = 0 |  | ||||||
| 	} |  | ||||||
| 	if exp < 0 { |  | ||||||
| 		ch = '-' |  | ||||||
| 		exp = -exp |  | ||||||
| 	} else { |  | ||||||
| 		ch = '+' |  | ||||||
| 	} |  | ||||||
| 	dst = append(dst, ch) |  | ||||||
|  |  | ||||||
| 	// dddd |  | ||||||
| 	var buf [3]byte |  | ||||||
| 	i := len(buf) |  | ||||||
| 	for exp >= 10 { |  | ||||||
| 		i-- |  | ||||||
| 		buf[i] = byte(exp%10 + '0') |  | ||||||
| 		exp /= 10 |  | ||||||
| 	} |  | ||||||
| 	// exp < 10 |  | ||||||
| 	i-- |  | ||||||
| 	buf[i] = byte(exp + '0') |  | ||||||
|  |  | ||||||
| 	switch i { |  | ||||||
| 	case 0: |  | ||||||
| 		dst = append(dst, buf[0], buf[1], buf[2]) |  | ||||||
| 	case 1: |  | ||||||
| 		dst = append(dst, buf[1], buf[2]) |  | ||||||
| 	case 2: |  | ||||||
| 		// leading zeroes |  | ||||||
| 		dst = append(dst, '0', buf[2]) |  | ||||||
| 	} |  | ||||||
| 	return dst |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // %f: -ddddddd.ddddd |  | ||||||
| func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte { |  | ||||||
| 	// sign |  | ||||||
| 	if neg { |  | ||||||
| 		dst = append(dst, '-') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// integer, padded with zeros as needed. |  | ||||||
| 	if d.dp > 0 { |  | ||||||
| 		var i int |  | ||||||
| 		for i = 0; i < d.dp && i < d.nd; i++ { |  | ||||||
| 			dst = append(dst, d.d[i]) |  | ||||||
| 		} |  | ||||||
| 		for ; i < d.dp; i++ { |  | ||||||
| 			dst = append(dst, '0') |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		dst = append(dst, '0') |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// fraction |  | ||||||
| 	if prec > 0 { |  | ||||||
| 		dst = append(dst, '.') |  | ||||||
| 		for i := 0; i < prec; i++ { |  | ||||||
| 			ch := byte('0') |  | ||||||
| 			if j := d.dp + i; 0 <= j && j < d.nd { |  | ||||||
| 				ch = d.d[j] |  | ||||||
| 			} |  | ||||||
| 			dst = append(dst, ch) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return dst |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // %b: -ddddddddp+ddd |  | ||||||
| func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte { |  | ||||||
| 	var buf [50]byte |  | ||||||
| 	w := len(buf) |  | ||||||
| 	exp -= int(flt.mantbits) |  | ||||||
| 	esign := byte('+') |  | ||||||
| 	if exp < 0 { |  | ||||||
| 		esign = '-' |  | ||||||
| 		exp = -exp |  | ||||||
| 	} |  | ||||||
| 	n := 0 |  | ||||||
| 	for exp > 0 || n < 1 { |  | ||||||
| 		n++ |  | ||||||
| 		w-- |  | ||||||
| 		buf[w] = byte(exp%10 + '0') |  | ||||||
| 		exp /= 10 |  | ||||||
| 	} |  | ||||||
| 	w-- |  | ||||||
| 	buf[w] = esign |  | ||||||
| 	w-- |  | ||||||
| 	buf[w] = 'p' |  | ||||||
| 	n = 0 |  | ||||||
| 	for mant > 0 || n < 1 { |  | ||||||
| 		n++ |  | ||||||
| 		w-- |  | ||||||
| 		buf[w] = byte(mant%10 + '0') |  | ||||||
| 		mant /= 10 |  | ||||||
| 	} |  | ||||||
| 	if neg { |  | ||||||
| 		w-- |  | ||||||
| 		buf[w] = '-' |  | ||||||
| 	} |  | ||||||
| 	return append(dst, buf[w:]...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func max(a, b int) int { |  | ||||||
| 	if a > b { |  | ||||||
| 		return a |  | ||||||
| 	} |  | ||||||
| 	return b |  | ||||||
| } |  | ||||||
							
								
								
									
										161
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/iota.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										161
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/iota.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,161 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Portions of this file are on Go stdlib's strconv/iota.go */ |  | ||||||
| // Copyright 2009 The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	digits   = "0123456789abcdefghijklmnopqrstuvwxyz" |  | ||||||
| 	digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" |  | ||||||
| 	digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var shifts = [len(digits) + 1]uint{ |  | ||||||
| 	1 << 1: 1, |  | ||||||
| 	1 << 2: 2, |  | ||||||
| 	1 << 3: 3, |  | ||||||
| 	1 << 4: 4, |  | ||||||
| 	1 << 5: 5, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var smallNumbers = [][]byte{ |  | ||||||
| 	[]byte("0"), |  | ||||||
| 	[]byte("1"), |  | ||||||
| 	[]byte("2"), |  | ||||||
| 	[]byte("3"), |  | ||||||
| 	[]byte("4"), |  | ||||||
| 	[]byte("5"), |  | ||||||
| 	[]byte("6"), |  | ||||||
| 	[]byte("7"), |  | ||||||
| 	[]byte("8"), |  | ||||||
| 	[]byte("9"), |  | ||||||
| 	[]byte("10"), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type FormatBitsWriter interface { |  | ||||||
| 	io.Writer |  | ||||||
| 	io.ByteWriter |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type FormatBitsScratch struct{} |  | ||||||
|  |  | ||||||
| // |  | ||||||
| // DEPRECIATED: `scratch` is no longer used, FormatBits2 is available. |  | ||||||
| // |  | ||||||
| // FormatBits computes the string representation of u in the given base. |  | ||||||
| // If neg is set, u is treated as negative int64 value. If append_ is |  | ||||||
| // set, the string is appended to dst and the resulting byte slice is |  | ||||||
| // returned as the first result value; otherwise the string is returned |  | ||||||
| // as the second result value. |  | ||||||
| // |  | ||||||
| func FormatBits(scratch *FormatBitsScratch, dst FormatBitsWriter, u uint64, base int, neg bool) { |  | ||||||
| 	FormatBits2(dst, u, base, neg) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // FormatBits2 computes the string representation of u in the given base. |  | ||||||
| // If neg is set, u is treated as negative int64 value. If append_ is |  | ||||||
| // set, the string is appended to dst and the resulting byte slice is |  | ||||||
| // returned as the first result value; otherwise the string is returned |  | ||||||
| // as the second result value. |  | ||||||
| // |  | ||||||
| func FormatBits2(dst FormatBitsWriter, u uint64, base int, neg bool) { |  | ||||||
| 	if base < 2 || base > len(digits) { |  | ||||||
| 		panic("strconv: illegal AppendInt/FormatInt base") |  | ||||||
| 	} |  | ||||||
| 	// fast path for small common numbers |  | ||||||
| 	if u <= 10 { |  | ||||||
| 		if neg { |  | ||||||
| 			dst.WriteByte('-') |  | ||||||
| 		} |  | ||||||
| 		dst.Write(smallNumbers[u]) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// 2 <= base && base <= len(digits) |  | ||||||
|  |  | ||||||
| 	var a = makeSlice(65) |  | ||||||
| 	//	var a [64 + 1]byte // +1 for sign of 64bit value in base 2 |  | ||||||
| 	i := len(a) |  | ||||||
|  |  | ||||||
| 	if neg { |  | ||||||
| 		u = -u |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// convert bits |  | ||||||
| 	if base == 10 { |  | ||||||
| 		// common case: use constants for / and % because |  | ||||||
| 		// the compiler can optimize it into a multiply+shift, |  | ||||||
| 		// and unroll loop |  | ||||||
| 		for u >= 100 { |  | ||||||
| 			i -= 2 |  | ||||||
| 			q := u / 100 |  | ||||||
| 			j := uintptr(u - q*100) |  | ||||||
| 			a[i+1] = digits01[j] |  | ||||||
| 			a[i+0] = digits10[j] |  | ||||||
| 			u = q |  | ||||||
| 		} |  | ||||||
| 		if u >= 10 { |  | ||||||
| 			i-- |  | ||||||
| 			q := u / 10 |  | ||||||
| 			a[i] = digits[uintptr(u-q*10)] |  | ||||||
| 			u = q |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	} else if s := shifts[base]; s > 0 { |  | ||||||
| 		// base is power of 2: use shifts and masks instead of / and % |  | ||||||
| 		b := uint64(base) |  | ||||||
| 		m := uintptr(b) - 1 // == 1<<s - 1 |  | ||||||
| 		for u >= b { |  | ||||||
| 			i-- |  | ||||||
| 			a[i] = digits[uintptr(u)&m] |  | ||||||
| 			u >>= s |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	} else { |  | ||||||
| 		// general case |  | ||||||
| 		b := uint64(base) |  | ||||||
| 		for u >= b { |  | ||||||
| 			i-- |  | ||||||
| 			a[i] = digits[uintptr(u%b)] |  | ||||||
| 			u /= b |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// u < base |  | ||||||
| 	i-- |  | ||||||
| 	a[i] = digits[uintptr(u)] |  | ||||||
|  |  | ||||||
| 	// add sign, if any |  | ||||||
| 	if neg { |  | ||||||
| 		i-- |  | ||||||
| 		a[i] = '-' |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	dst.Write(a[i:]) |  | ||||||
|  |  | ||||||
| 	Pool(a) |  | ||||||
|  |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
							
								
								
									
										512
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/jsonstring.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										512
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/jsonstring.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,512 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* Portions of this file are on Go stdlib's encoding/json/encode.go */ |  | ||||||
| // Copyright 2010 The Go Authors.  All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"io" |  | ||||||
| 	"unicode/utf8" |  | ||||||
| 	"strconv" |  | ||||||
| 	"unicode/utf16" |  | ||||||
| 	"unicode" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const hex = "0123456789abcdef" |  | ||||||
|  |  | ||||||
| type JsonStringWriter interface { |  | ||||||
| 	io.Writer |  | ||||||
| 	io.ByteWriter |  | ||||||
| 	stringWriter |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func WriteJsonString(buf JsonStringWriter, s string) { |  | ||||||
| 	WriteJson(buf, []byte(s)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Function ported from encoding/json: func (e *encodeState) string(s string) (int, error) |  | ||||||
|  */ |  | ||||||
| func WriteJson(buf JsonStringWriter, s []byte) { |  | ||||||
| 	buf.WriteByte('"') |  | ||||||
| 	start := 0 |  | ||||||
| 	for i := 0; i < len(s); { |  | ||||||
| 		if b := s[i]; b < utf8.RuneSelf { |  | ||||||
| 			/* |  | ||||||
| 				if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' { |  | ||||||
| 					i++ |  | ||||||
| 					continue |  | ||||||
| 				} |  | ||||||
| 			*/ |  | ||||||
| 			if lt[b] == true { |  | ||||||
| 				i++ |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if start < i { |  | ||||||
| 				buf.Write(s[start:i]) |  | ||||||
| 			} |  | ||||||
| 			switch b { |  | ||||||
| 			case '\\', '"': |  | ||||||
| 				buf.WriteByte('\\') |  | ||||||
| 				buf.WriteByte(b) |  | ||||||
| 			case '\n': |  | ||||||
| 				buf.WriteByte('\\') |  | ||||||
| 				buf.WriteByte('n') |  | ||||||
| 			case '\r': |  | ||||||
| 				buf.WriteByte('\\') |  | ||||||
| 				buf.WriteByte('r') |  | ||||||
| 			default: |  | ||||||
| 				// This encodes bytes < 0x20 except for \n and \r, |  | ||||||
| 				// as well as < and >. The latter are escaped because they |  | ||||||
| 				// can lead to security holes when user-controlled strings |  | ||||||
| 				// are rendered into JSON and served to some browsers. |  | ||||||
| 				buf.WriteString(`\u00`) |  | ||||||
| 				buf.WriteByte(hex[b>>4]) |  | ||||||
| 				buf.WriteByte(hex[b&0xF]) |  | ||||||
| 			} |  | ||||||
| 			i++ |  | ||||||
| 			start = i |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		c, size := utf8.DecodeRune(s[i:]) |  | ||||||
| 		if c == utf8.RuneError && size == 1 { |  | ||||||
| 			if start < i { |  | ||||||
| 				buf.Write(s[start:i]) |  | ||||||
| 			} |  | ||||||
| 			buf.WriteString(`\ufffd`) |  | ||||||
| 			i += size |  | ||||||
| 			start = i |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		// U+2028 is LINE SEPARATOR. |  | ||||||
| 		// U+2029 is PARAGRAPH SEPARATOR. |  | ||||||
| 		// They are both technically valid characters in JSON strings, |  | ||||||
| 		// but don't work in JSONP, which has to be evaluated as JavaScript, |  | ||||||
| 		// and can lead to security holes there. It is valid JSON to |  | ||||||
| 		// escape them, so we do so unconditionally. |  | ||||||
| 		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. |  | ||||||
| 		if c == '\u2028' || c == '\u2029' { |  | ||||||
| 			if start < i { |  | ||||||
| 				buf.Write(s[start:i]) |  | ||||||
| 			} |  | ||||||
| 			buf.WriteString(`\u202`) |  | ||||||
| 			buf.WriteByte(hex[c&0xF]) |  | ||||||
| 			i += size |  | ||||||
| 			start = i |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		i += size |  | ||||||
| 	} |  | ||||||
| 	if start < len(s) { |  | ||||||
| 		buf.Write(s[start:]) |  | ||||||
| 	} |  | ||||||
| 	buf.WriteByte('"') |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // UnquoteBytes will decode []byte containing json string to go string |  | ||||||
| // ported from encoding/json/decode.go |  | ||||||
| func UnquoteBytes(s []byte) (t []byte, ok bool) { |  | ||||||
| 	if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	s = s[1 : len(s)-1] |  | ||||||
|  |  | ||||||
| 	// Check for unusual characters. If there are none, |  | ||||||
| 	// then no unquoting is needed, so return a slice of the |  | ||||||
| 	// original bytes. |  | ||||||
| 	r := 0 |  | ||||||
| 	for r < len(s) { |  | ||||||
| 		c := s[r] |  | ||||||
| 		if c == '\\' || c == '"' || c < ' ' { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		if c < utf8.RuneSelf { |  | ||||||
| 			r++ |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		rr, size := utf8.DecodeRune(s[r:]) |  | ||||||
| 		if rr == utf8.RuneError && size == 1 { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		r += size |  | ||||||
| 	} |  | ||||||
| 	if r == len(s) { |  | ||||||
| 		return s, true |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	b := make([]byte, len(s)+2*utf8.UTFMax) |  | ||||||
| 	w := copy(b, s[0:r]) |  | ||||||
| 	for r < len(s) { |  | ||||||
| 		// Out of room?  Can only happen if s is full of |  | ||||||
| 		// malformed UTF-8 and we're replacing each |  | ||||||
| 		// byte with RuneError. |  | ||||||
| 		if w >= len(b)-2*utf8.UTFMax { |  | ||||||
| 			nb := make([]byte, (len(b)+utf8.UTFMax)*2) |  | ||||||
| 			copy(nb, b[0:w]) |  | ||||||
| 			b = nb |  | ||||||
| 		} |  | ||||||
| 		switch c := s[r]; { |  | ||||||
| 		case c == '\\': |  | ||||||
| 			r++ |  | ||||||
| 			if r >= len(s) { |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			switch s[r] { |  | ||||||
| 			default: |  | ||||||
| 				return |  | ||||||
| 			case '"', '\\', '/', '\'': |  | ||||||
| 				b[w] = s[r] |  | ||||||
| 				r++ |  | ||||||
| 				w++ |  | ||||||
| 			case 'b': |  | ||||||
| 				b[w] = '\b' |  | ||||||
| 				r++ |  | ||||||
| 				w++ |  | ||||||
| 			case 'f': |  | ||||||
| 				b[w] = '\f' |  | ||||||
| 				r++ |  | ||||||
| 				w++ |  | ||||||
| 			case 'n': |  | ||||||
| 				b[w] = '\n' |  | ||||||
| 				r++ |  | ||||||
| 				w++ |  | ||||||
| 			case 'r': |  | ||||||
| 				b[w] = '\r' |  | ||||||
| 				r++ |  | ||||||
| 				w++ |  | ||||||
| 			case 't': |  | ||||||
| 				b[w] = '\t' |  | ||||||
| 				r++ |  | ||||||
| 				w++ |  | ||||||
| 			case 'u': |  | ||||||
| 				r-- |  | ||||||
| 				rr := getu4(s[r:]) |  | ||||||
| 				if rr < 0 { |  | ||||||
| 					return |  | ||||||
| 				} |  | ||||||
| 				r += 6 |  | ||||||
| 				if utf16.IsSurrogate(rr) { |  | ||||||
| 					rr1 := getu4(s[r:]) |  | ||||||
| 					if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { |  | ||||||
| 						// A valid pair; consume. |  | ||||||
| 						r += 6 |  | ||||||
| 						w += utf8.EncodeRune(b[w:], dec) |  | ||||||
| 						break |  | ||||||
| 					} |  | ||||||
| 					// Invalid surrogate; fall back to replacement rune. |  | ||||||
| 					rr = unicode.ReplacementChar |  | ||||||
| 				} |  | ||||||
| 				w += utf8.EncodeRune(b[w:], rr) |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 		// Quote, control characters are invalid. |  | ||||||
| 		case c == '"', c < ' ': |  | ||||||
| 			return |  | ||||||
|  |  | ||||||
| 		// ASCII |  | ||||||
| 		case c < utf8.RuneSelf: |  | ||||||
| 			b[w] = c |  | ||||||
| 			r++ |  | ||||||
| 			w++ |  | ||||||
|  |  | ||||||
| 		// Coerce to well-formed UTF-8. |  | ||||||
| 		default: |  | ||||||
| 			rr, size := utf8.DecodeRune(s[r:]) |  | ||||||
| 			r += size |  | ||||||
| 			w += utf8.EncodeRune(b[w:], rr) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return b[0:w], true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // getu4 decodes \uXXXX from the beginning of s, returning the hex value, |  | ||||||
| // or it returns -1. |  | ||||||
| func getu4(s []byte) rune { |  | ||||||
| 	if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
| 	r, err := strconv.ParseUint(string(s[2:6]), 16, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
| 	return rune(r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO(pquerna): consider combining wibth the normal byte mask. |  | ||||||
| var lt [256]bool = [256]bool{ |  | ||||||
| 	false, /* 0 */ |  | ||||||
| 	false, /* 1 */ |  | ||||||
| 	false, /* 2 */ |  | ||||||
| 	false, /* 3 */ |  | ||||||
| 	false, /* 4 */ |  | ||||||
| 	false, /* 5 */ |  | ||||||
| 	false, /* 6 */ |  | ||||||
| 	false, /* 7 */ |  | ||||||
| 	false, /* 8 */ |  | ||||||
| 	false, /* 9 */ |  | ||||||
| 	false, /* 10 */ |  | ||||||
| 	false, /* 11 */ |  | ||||||
| 	false, /* 12 */ |  | ||||||
| 	false, /* 13 */ |  | ||||||
| 	false, /* 14 */ |  | ||||||
| 	false, /* 15 */ |  | ||||||
| 	false, /* 16 */ |  | ||||||
| 	false, /* 17 */ |  | ||||||
| 	false, /* 18 */ |  | ||||||
| 	false, /* 19 */ |  | ||||||
| 	false, /* 20 */ |  | ||||||
| 	false, /* 21 */ |  | ||||||
| 	false, /* 22 */ |  | ||||||
| 	false, /* 23 */ |  | ||||||
| 	false, /* 24 */ |  | ||||||
| 	false, /* 25 */ |  | ||||||
| 	false, /* 26 */ |  | ||||||
| 	false, /* 27 */ |  | ||||||
| 	false, /* 28 */ |  | ||||||
| 	false, /* 29 */ |  | ||||||
| 	false, /* 30 */ |  | ||||||
| 	false, /* 31 */ |  | ||||||
| 	true,  /* 32 */ |  | ||||||
| 	true,  /* 33 */ |  | ||||||
| 	false, /* 34 */ |  | ||||||
| 	true,  /* 35 */ |  | ||||||
| 	true,  /* 36 */ |  | ||||||
| 	true,  /* 37 */ |  | ||||||
| 	false, /* 38 */ |  | ||||||
| 	true,  /* 39 */ |  | ||||||
| 	true,  /* 40 */ |  | ||||||
| 	true,  /* 41 */ |  | ||||||
| 	true,  /* 42 */ |  | ||||||
| 	true,  /* 43 */ |  | ||||||
| 	true,  /* 44 */ |  | ||||||
| 	true,  /* 45 */ |  | ||||||
| 	true,  /* 46 */ |  | ||||||
| 	true,  /* 47 */ |  | ||||||
| 	true,  /* 48 */ |  | ||||||
| 	true,  /* 49 */ |  | ||||||
| 	true,  /* 50 */ |  | ||||||
| 	true,  /* 51 */ |  | ||||||
| 	true,  /* 52 */ |  | ||||||
| 	true,  /* 53 */ |  | ||||||
| 	true,  /* 54 */ |  | ||||||
| 	true,  /* 55 */ |  | ||||||
| 	true,  /* 56 */ |  | ||||||
| 	true,  /* 57 */ |  | ||||||
| 	true,  /* 58 */ |  | ||||||
| 	true,  /* 59 */ |  | ||||||
| 	false, /* 60 */ |  | ||||||
| 	true,  /* 61 */ |  | ||||||
| 	false, /* 62 */ |  | ||||||
| 	true,  /* 63 */ |  | ||||||
| 	true,  /* 64 */ |  | ||||||
| 	true,  /* 65 */ |  | ||||||
| 	true,  /* 66 */ |  | ||||||
| 	true,  /* 67 */ |  | ||||||
| 	true,  /* 68 */ |  | ||||||
| 	true,  /* 69 */ |  | ||||||
| 	true,  /* 70 */ |  | ||||||
| 	true,  /* 71 */ |  | ||||||
| 	true,  /* 72 */ |  | ||||||
| 	true,  /* 73 */ |  | ||||||
| 	true,  /* 74 */ |  | ||||||
| 	true,  /* 75 */ |  | ||||||
| 	true,  /* 76 */ |  | ||||||
| 	true,  /* 77 */ |  | ||||||
| 	true,  /* 78 */ |  | ||||||
| 	true,  /* 79 */ |  | ||||||
| 	true,  /* 80 */ |  | ||||||
| 	true,  /* 81 */ |  | ||||||
| 	true,  /* 82 */ |  | ||||||
| 	true,  /* 83 */ |  | ||||||
| 	true,  /* 84 */ |  | ||||||
| 	true,  /* 85 */ |  | ||||||
| 	true,  /* 86 */ |  | ||||||
| 	true,  /* 87 */ |  | ||||||
| 	true,  /* 88 */ |  | ||||||
| 	true,  /* 89 */ |  | ||||||
| 	true,  /* 90 */ |  | ||||||
| 	true,  /* 91 */ |  | ||||||
| 	false, /* 92 */ |  | ||||||
| 	true,  /* 93 */ |  | ||||||
| 	true,  /* 94 */ |  | ||||||
| 	true,  /* 95 */ |  | ||||||
| 	true,  /* 96 */ |  | ||||||
| 	true,  /* 97 */ |  | ||||||
| 	true,  /* 98 */ |  | ||||||
| 	true,  /* 99 */ |  | ||||||
| 	true,  /* 100 */ |  | ||||||
| 	true,  /* 101 */ |  | ||||||
| 	true,  /* 102 */ |  | ||||||
| 	true,  /* 103 */ |  | ||||||
| 	true,  /* 104 */ |  | ||||||
| 	true,  /* 105 */ |  | ||||||
| 	true,  /* 106 */ |  | ||||||
| 	true,  /* 107 */ |  | ||||||
| 	true,  /* 108 */ |  | ||||||
| 	true,  /* 109 */ |  | ||||||
| 	true,  /* 110 */ |  | ||||||
| 	true,  /* 111 */ |  | ||||||
| 	true,  /* 112 */ |  | ||||||
| 	true,  /* 113 */ |  | ||||||
| 	true,  /* 114 */ |  | ||||||
| 	true,  /* 115 */ |  | ||||||
| 	true,  /* 116 */ |  | ||||||
| 	true,  /* 117 */ |  | ||||||
| 	true,  /* 118 */ |  | ||||||
| 	true,  /* 119 */ |  | ||||||
| 	true,  /* 120 */ |  | ||||||
| 	true,  /* 121 */ |  | ||||||
| 	true,  /* 122 */ |  | ||||||
| 	true,  /* 123 */ |  | ||||||
| 	true,  /* 124 */ |  | ||||||
| 	true,  /* 125 */ |  | ||||||
| 	true,  /* 126 */ |  | ||||||
| 	true,  /* 127 */ |  | ||||||
| 	true,  /* 128 */ |  | ||||||
| 	true,  /* 129 */ |  | ||||||
| 	true,  /* 130 */ |  | ||||||
| 	true,  /* 131 */ |  | ||||||
| 	true,  /* 132 */ |  | ||||||
| 	true,  /* 133 */ |  | ||||||
| 	true,  /* 134 */ |  | ||||||
| 	true,  /* 135 */ |  | ||||||
| 	true,  /* 136 */ |  | ||||||
| 	true,  /* 137 */ |  | ||||||
| 	true,  /* 138 */ |  | ||||||
| 	true,  /* 139 */ |  | ||||||
| 	true,  /* 140 */ |  | ||||||
| 	true,  /* 141 */ |  | ||||||
| 	true,  /* 142 */ |  | ||||||
| 	true,  /* 143 */ |  | ||||||
| 	true,  /* 144 */ |  | ||||||
| 	true,  /* 145 */ |  | ||||||
| 	true,  /* 146 */ |  | ||||||
| 	true,  /* 147 */ |  | ||||||
| 	true,  /* 148 */ |  | ||||||
| 	true,  /* 149 */ |  | ||||||
| 	true,  /* 150 */ |  | ||||||
| 	true,  /* 151 */ |  | ||||||
| 	true,  /* 152 */ |  | ||||||
| 	true,  /* 153 */ |  | ||||||
| 	true,  /* 154 */ |  | ||||||
| 	true,  /* 155 */ |  | ||||||
| 	true,  /* 156 */ |  | ||||||
| 	true,  /* 157 */ |  | ||||||
| 	true,  /* 158 */ |  | ||||||
| 	true,  /* 159 */ |  | ||||||
| 	true,  /* 160 */ |  | ||||||
| 	true,  /* 161 */ |  | ||||||
| 	true,  /* 162 */ |  | ||||||
| 	true,  /* 163 */ |  | ||||||
| 	true,  /* 164 */ |  | ||||||
| 	true,  /* 165 */ |  | ||||||
| 	true,  /* 166 */ |  | ||||||
| 	true,  /* 167 */ |  | ||||||
| 	true,  /* 168 */ |  | ||||||
| 	true,  /* 169 */ |  | ||||||
| 	true,  /* 170 */ |  | ||||||
| 	true,  /* 171 */ |  | ||||||
| 	true,  /* 172 */ |  | ||||||
| 	true,  /* 173 */ |  | ||||||
| 	true,  /* 174 */ |  | ||||||
| 	true,  /* 175 */ |  | ||||||
| 	true,  /* 176 */ |  | ||||||
| 	true,  /* 177 */ |  | ||||||
| 	true,  /* 178 */ |  | ||||||
| 	true,  /* 179 */ |  | ||||||
| 	true,  /* 180 */ |  | ||||||
| 	true,  /* 181 */ |  | ||||||
| 	true,  /* 182 */ |  | ||||||
| 	true,  /* 183 */ |  | ||||||
| 	true,  /* 184 */ |  | ||||||
| 	true,  /* 185 */ |  | ||||||
| 	true,  /* 186 */ |  | ||||||
| 	true,  /* 187 */ |  | ||||||
| 	true,  /* 188 */ |  | ||||||
| 	true,  /* 189 */ |  | ||||||
| 	true,  /* 190 */ |  | ||||||
| 	true,  /* 191 */ |  | ||||||
| 	true,  /* 192 */ |  | ||||||
| 	true,  /* 193 */ |  | ||||||
| 	true,  /* 194 */ |  | ||||||
| 	true,  /* 195 */ |  | ||||||
| 	true,  /* 196 */ |  | ||||||
| 	true,  /* 197 */ |  | ||||||
| 	true,  /* 198 */ |  | ||||||
| 	true,  /* 199 */ |  | ||||||
| 	true,  /* 200 */ |  | ||||||
| 	true,  /* 201 */ |  | ||||||
| 	true,  /* 202 */ |  | ||||||
| 	true,  /* 203 */ |  | ||||||
| 	true,  /* 204 */ |  | ||||||
| 	true,  /* 205 */ |  | ||||||
| 	true,  /* 206 */ |  | ||||||
| 	true,  /* 207 */ |  | ||||||
| 	true,  /* 208 */ |  | ||||||
| 	true,  /* 209 */ |  | ||||||
| 	true,  /* 210 */ |  | ||||||
| 	true,  /* 211 */ |  | ||||||
| 	true,  /* 212 */ |  | ||||||
| 	true,  /* 213 */ |  | ||||||
| 	true,  /* 214 */ |  | ||||||
| 	true,  /* 215 */ |  | ||||||
| 	true,  /* 216 */ |  | ||||||
| 	true,  /* 217 */ |  | ||||||
| 	true,  /* 218 */ |  | ||||||
| 	true,  /* 219 */ |  | ||||||
| 	true,  /* 220 */ |  | ||||||
| 	true,  /* 221 */ |  | ||||||
| 	true,  /* 222 */ |  | ||||||
| 	true,  /* 223 */ |  | ||||||
| 	true,  /* 224 */ |  | ||||||
| 	true,  /* 225 */ |  | ||||||
| 	true,  /* 226 */ |  | ||||||
| 	true,  /* 227 */ |  | ||||||
| 	true,  /* 228 */ |  | ||||||
| 	true,  /* 229 */ |  | ||||||
| 	true,  /* 230 */ |  | ||||||
| 	true,  /* 231 */ |  | ||||||
| 	true,  /* 232 */ |  | ||||||
| 	true,  /* 233 */ |  | ||||||
| 	true,  /* 234 */ |  | ||||||
| 	true,  /* 235 */ |  | ||||||
| 	true,  /* 236 */ |  | ||||||
| 	true,  /* 237 */ |  | ||||||
| 	true,  /* 238 */ |  | ||||||
| 	true,  /* 239 */ |  | ||||||
| 	true,  /* 240 */ |  | ||||||
| 	true,  /* 241 */ |  | ||||||
| 	true,  /* 242 */ |  | ||||||
| 	true,  /* 243 */ |  | ||||||
| 	true,  /* 244 */ |  | ||||||
| 	true,  /* 245 */ |  | ||||||
| 	true,  /* 246 */ |  | ||||||
| 	true,  /* 247 */ |  | ||||||
| 	true,  /* 248 */ |  | ||||||
| 	true,  /* 249 */ |  | ||||||
| 	true,  /* 250 */ |  | ||||||
| 	true,  /* 251 */ |  | ||||||
| 	true,  /* 252 */ |  | ||||||
| 	true,  /* 253 */ |  | ||||||
| 	true,  /* 254 */ |  | ||||||
| 	true,  /* 255 */ |  | ||||||
| } |  | ||||||
							
								
								
									
										1000
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/lexer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1000
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/lexer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										513
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										513
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,513 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"unicode" |  | ||||||
| 	"unicode/utf16" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const sliceStringMask = cIJC | cNFP |  | ||||||
|  |  | ||||||
| type ffReader struct { |  | ||||||
| 	s []byte |  | ||||||
| 	i int |  | ||||||
| 	l int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func newffReader(d []byte) *ffReader { |  | ||||||
| 	return &ffReader{ |  | ||||||
| 		s: d, |  | ||||||
| 		i: 0, |  | ||||||
| 		l: len(d), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) Slice(start, stop int) []byte { |  | ||||||
| 	return r.s[start:stop] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) Pos() int { |  | ||||||
| 	return r.i |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Reset the reader, and add new input. |  | ||||||
| func (r *ffReader) Reset(d []byte) { |  | ||||||
| 	r.s = d |  | ||||||
| 	r.i = 0 |  | ||||||
| 	r.l = len(d) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Calcuates the Position with line and line offset, |  | ||||||
| // because this isn't counted for performance reasons, |  | ||||||
| // it will iterate the buffer from the beginning, and should |  | ||||||
| // only be used in error-paths. |  | ||||||
| func (r *ffReader) PosWithLine() (int, int) { |  | ||||||
| 	currentLine := 1 |  | ||||||
| 	currentChar := 0 |  | ||||||
|  |  | ||||||
| 	for i := 0; i < r.i; i++ { |  | ||||||
| 		c := r.s[i] |  | ||||||
| 		currentChar++ |  | ||||||
| 		if c == '\n' { |  | ||||||
| 			currentLine++ |  | ||||||
| 			currentChar = 0 |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return currentLine, currentChar |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) ReadByteNoWS() (byte, error) { |  | ||||||
| 	if r.i >= r.l { |  | ||||||
| 		return 0, io.EOF |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	j := r.i |  | ||||||
|  |  | ||||||
| 	for { |  | ||||||
| 		c := r.s[j] |  | ||||||
| 		j++ |  | ||||||
|  |  | ||||||
| 		// inline whitespace parsing gives another ~8% performance boost |  | ||||||
| 		// for many kinds of nicely indented JSON. |  | ||||||
| 		// ... and using a [255]bool instead of multiple ifs, gives another 2% |  | ||||||
| 		/* |  | ||||||
| 			if c != '\t' && |  | ||||||
| 				c != '\n' && |  | ||||||
| 				c != '\v' && |  | ||||||
| 				c != '\f' && |  | ||||||
| 				c != '\r' && |  | ||||||
| 				c != ' ' { |  | ||||||
| 				r.i = j |  | ||||||
| 				return c, nil |  | ||||||
| 			} |  | ||||||
| 		*/ |  | ||||||
| 		if whitespaceLookupTable[c] == false { |  | ||||||
| 			r.i = j |  | ||||||
| 			return c, nil |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if j >= r.l { |  | ||||||
| 			return 0, io.EOF |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) ReadByte() (byte, error) { |  | ||||||
| 	if r.i >= r.l { |  | ||||||
| 		return 0, io.EOF |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	r.i++ |  | ||||||
|  |  | ||||||
| 	return r.s[r.i-1], nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) UnreadByte() { |  | ||||||
| 	if r.i <= 0 { |  | ||||||
| 		panic("ffReader.UnreadByte: at beginning of slice") |  | ||||||
| 	} |  | ||||||
| 	r.i-- |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) readU4(j int) (rune, error) { |  | ||||||
|  |  | ||||||
| 	var u4 [4]byte |  | ||||||
| 	for i := 0; i < 4; i++ { |  | ||||||
| 		if j >= r.l { |  | ||||||
| 			return -1, io.EOF |  | ||||||
| 		} |  | ||||||
| 		c := r.s[j] |  | ||||||
| 		if byteLookupTable[c]&cVHC != 0 { |  | ||||||
| 			u4[i] = c |  | ||||||
| 			j++ |  | ||||||
| 			continue |  | ||||||
| 		} else { |  | ||||||
| 			// TODO(pquerna): handle errors better. layering violation. |  | ||||||
| 			return -1, fmt.Errorf("lex_string_invalid_hex_char: %v %v", c, string(u4[:])) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// TODO(pquerna): utf16.IsSurrogate |  | ||||||
| 	rr, err := ParseUint(u4[:], 16, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return -1, err |  | ||||||
| 	} |  | ||||||
| 	return rune(rr), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) handleEscaped(c byte, j int, out DecodingBuffer) (int, error) { |  | ||||||
| 	if j >= r.l { |  | ||||||
| 		return 0, io.EOF |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	c = r.s[j] |  | ||||||
| 	j++ |  | ||||||
|  |  | ||||||
| 	if c == 'u' { |  | ||||||
| 		ru, err := r.readU4(j) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if utf16.IsSurrogate(ru) { |  | ||||||
| 			ru2, err := r.readU4(j + 6) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return 0, err |  | ||||||
| 			} |  | ||||||
| 			out.Write(r.s[r.i : j-2]) |  | ||||||
| 			r.i = j + 10 |  | ||||||
| 			j = r.i |  | ||||||
| 			rval := utf16.DecodeRune(ru, ru2) |  | ||||||
| 			if rval != unicode.ReplacementChar { |  | ||||||
| 				out.WriteRune(rval) |  | ||||||
| 			} else { |  | ||||||
| 				return 0, fmt.Errorf("lex_string_invalid_unicode_surrogate: %v %v", ru, ru2) |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			out.Write(r.s[r.i : j-2]) |  | ||||||
| 			r.i = j + 4 |  | ||||||
| 			j = r.i |  | ||||||
| 			out.WriteRune(ru) |  | ||||||
| 		} |  | ||||||
| 		return j, nil |  | ||||||
| 	} else if byteLookupTable[c]&cVEC == 0 { |  | ||||||
| 		return 0, fmt.Errorf("lex_string_invalid_escaped_char: %v", c) |  | ||||||
| 	} else { |  | ||||||
| 		out.Write(r.s[r.i : j-2]) |  | ||||||
| 		r.i = j |  | ||||||
| 		j = r.i |  | ||||||
|  |  | ||||||
| 		switch c { |  | ||||||
| 		case '"': |  | ||||||
| 			out.WriteByte('"') |  | ||||||
| 		case '\\': |  | ||||||
| 			out.WriteByte('\\') |  | ||||||
| 		case '/': |  | ||||||
| 			out.WriteByte('/') |  | ||||||
| 		case 'b': |  | ||||||
| 			out.WriteByte('\b') |  | ||||||
| 		case 'f': |  | ||||||
| 			out.WriteByte('\f') |  | ||||||
| 		case 'n': |  | ||||||
| 			out.WriteByte('\n') |  | ||||||
| 		case 'r': |  | ||||||
| 			out.WriteByte('\r') |  | ||||||
| 		case 't': |  | ||||||
| 			out.WriteByte('\t') |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return j, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *ffReader) SliceString(out DecodingBuffer) error { |  | ||||||
| 	var c byte |  | ||||||
| 	// TODO(pquerna): string_with_escapes? de-escape here? |  | ||||||
| 	j := r.i |  | ||||||
|  |  | ||||||
| 	for { |  | ||||||
| 		if j >= r.l { |  | ||||||
| 			return io.EOF |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		j, c = scanString(r.s, j) |  | ||||||
|  |  | ||||||
| 		if c == '"' { |  | ||||||
| 			if j != r.i { |  | ||||||
| 				out.Write(r.s[r.i : j-1]) |  | ||||||
| 				r.i = j |  | ||||||
| 			} |  | ||||||
| 			return nil |  | ||||||
| 		} else if c == '\\' { |  | ||||||
| 			var err error |  | ||||||
| 			j, err = r.handleEscaped(c, j, out) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} else if byteLookupTable[c]&cIJC != 0 { |  | ||||||
| 			return fmt.Errorf("lex_string_invalid_json_char: %v", c) |  | ||||||
| 		} |  | ||||||
| 		continue |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	panic("ffjson: SliceString unreached exit") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO(pquerna): consider combining wibth the normal byte mask. |  | ||||||
| var whitespaceLookupTable [256]bool = [256]bool{ |  | ||||||
| 	false, /* 0 */ |  | ||||||
| 	false, /* 1 */ |  | ||||||
| 	false, /* 2 */ |  | ||||||
| 	false, /* 3 */ |  | ||||||
| 	false, /* 4 */ |  | ||||||
| 	false, /* 5 */ |  | ||||||
| 	false, /* 6 */ |  | ||||||
| 	false, /* 7 */ |  | ||||||
| 	false, /* 8 */ |  | ||||||
| 	true,  /* 9 */ |  | ||||||
| 	true,  /* 10 */ |  | ||||||
| 	true,  /* 11 */ |  | ||||||
| 	true,  /* 12 */ |  | ||||||
| 	true,  /* 13 */ |  | ||||||
| 	false, /* 14 */ |  | ||||||
| 	false, /* 15 */ |  | ||||||
| 	false, /* 16 */ |  | ||||||
| 	false, /* 17 */ |  | ||||||
| 	false, /* 18 */ |  | ||||||
| 	false, /* 19 */ |  | ||||||
| 	false, /* 20 */ |  | ||||||
| 	false, /* 21 */ |  | ||||||
| 	false, /* 22 */ |  | ||||||
| 	false, /* 23 */ |  | ||||||
| 	false, /* 24 */ |  | ||||||
| 	false, /* 25 */ |  | ||||||
| 	false, /* 26 */ |  | ||||||
| 	false, /* 27 */ |  | ||||||
| 	false, /* 28 */ |  | ||||||
| 	false, /* 29 */ |  | ||||||
| 	false, /* 30 */ |  | ||||||
| 	false, /* 31 */ |  | ||||||
| 	true,  /* 32 */ |  | ||||||
| 	false, /* 33 */ |  | ||||||
| 	false, /* 34 */ |  | ||||||
| 	false, /* 35 */ |  | ||||||
| 	false, /* 36 */ |  | ||||||
| 	false, /* 37 */ |  | ||||||
| 	false, /* 38 */ |  | ||||||
| 	false, /* 39 */ |  | ||||||
| 	false, /* 40 */ |  | ||||||
| 	false, /* 41 */ |  | ||||||
| 	false, /* 42 */ |  | ||||||
| 	false, /* 43 */ |  | ||||||
| 	false, /* 44 */ |  | ||||||
| 	false, /* 45 */ |  | ||||||
| 	false, /* 46 */ |  | ||||||
| 	false, /* 47 */ |  | ||||||
| 	false, /* 48 */ |  | ||||||
| 	false, /* 49 */ |  | ||||||
| 	false, /* 50 */ |  | ||||||
| 	false, /* 51 */ |  | ||||||
| 	false, /* 52 */ |  | ||||||
| 	false, /* 53 */ |  | ||||||
| 	false, /* 54 */ |  | ||||||
| 	false, /* 55 */ |  | ||||||
| 	false, /* 56 */ |  | ||||||
| 	false, /* 57 */ |  | ||||||
| 	false, /* 58 */ |  | ||||||
| 	false, /* 59 */ |  | ||||||
| 	false, /* 60 */ |  | ||||||
| 	false, /* 61 */ |  | ||||||
| 	false, /* 62 */ |  | ||||||
| 	false, /* 63 */ |  | ||||||
| 	false, /* 64 */ |  | ||||||
| 	false, /* 65 */ |  | ||||||
| 	false, /* 66 */ |  | ||||||
| 	false, /* 67 */ |  | ||||||
| 	false, /* 68 */ |  | ||||||
| 	false, /* 69 */ |  | ||||||
| 	false, /* 70 */ |  | ||||||
| 	false, /* 71 */ |  | ||||||
| 	false, /* 72 */ |  | ||||||
| 	false, /* 73 */ |  | ||||||
| 	false, /* 74 */ |  | ||||||
| 	false, /* 75 */ |  | ||||||
| 	false, /* 76 */ |  | ||||||
| 	false, /* 77 */ |  | ||||||
| 	false, /* 78 */ |  | ||||||
| 	false, /* 79 */ |  | ||||||
| 	false, /* 80 */ |  | ||||||
| 	false, /* 81 */ |  | ||||||
| 	false, /* 82 */ |  | ||||||
| 	false, /* 83 */ |  | ||||||
| 	false, /* 84 */ |  | ||||||
| 	false, /* 85 */ |  | ||||||
| 	false, /* 86 */ |  | ||||||
| 	false, /* 87 */ |  | ||||||
| 	false, /* 88 */ |  | ||||||
| 	false, /* 89 */ |  | ||||||
| 	false, /* 90 */ |  | ||||||
| 	false, /* 91 */ |  | ||||||
| 	false, /* 92 */ |  | ||||||
| 	false, /* 93 */ |  | ||||||
| 	false, /* 94 */ |  | ||||||
| 	false, /* 95 */ |  | ||||||
| 	false, /* 96 */ |  | ||||||
| 	false, /* 97 */ |  | ||||||
| 	false, /* 98 */ |  | ||||||
| 	false, /* 99 */ |  | ||||||
| 	false, /* 100 */ |  | ||||||
| 	false, /* 101 */ |  | ||||||
| 	false, /* 102 */ |  | ||||||
| 	false, /* 103 */ |  | ||||||
| 	false, /* 104 */ |  | ||||||
| 	false, /* 105 */ |  | ||||||
| 	false, /* 106 */ |  | ||||||
| 	false, /* 107 */ |  | ||||||
| 	false, /* 108 */ |  | ||||||
| 	false, /* 109 */ |  | ||||||
| 	false, /* 110 */ |  | ||||||
| 	false, /* 111 */ |  | ||||||
| 	false, /* 112 */ |  | ||||||
| 	false, /* 113 */ |  | ||||||
| 	false, /* 114 */ |  | ||||||
| 	false, /* 115 */ |  | ||||||
| 	false, /* 116 */ |  | ||||||
| 	false, /* 117 */ |  | ||||||
| 	false, /* 118 */ |  | ||||||
| 	false, /* 119 */ |  | ||||||
| 	false, /* 120 */ |  | ||||||
| 	false, /* 121 */ |  | ||||||
| 	false, /* 122 */ |  | ||||||
| 	false, /* 123 */ |  | ||||||
| 	false, /* 124 */ |  | ||||||
| 	false, /* 125 */ |  | ||||||
| 	false, /* 126 */ |  | ||||||
| 	false, /* 127 */ |  | ||||||
| 	false, /* 128 */ |  | ||||||
| 	false, /* 129 */ |  | ||||||
| 	false, /* 130 */ |  | ||||||
| 	false, /* 131 */ |  | ||||||
| 	false, /* 132 */ |  | ||||||
| 	false, /* 133 */ |  | ||||||
| 	false, /* 134 */ |  | ||||||
| 	false, /* 135 */ |  | ||||||
| 	false, /* 136 */ |  | ||||||
| 	false, /* 137 */ |  | ||||||
| 	false, /* 138 */ |  | ||||||
| 	false, /* 139 */ |  | ||||||
| 	false, /* 140 */ |  | ||||||
| 	false, /* 141 */ |  | ||||||
| 	false, /* 142 */ |  | ||||||
| 	false, /* 143 */ |  | ||||||
| 	false, /* 144 */ |  | ||||||
| 	false, /* 145 */ |  | ||||||
| 	false, /* 146 */ |  | ||||||
| 	false, /* 147 */ |  | ||||||
| 	false, /* 148 */ |  | ||||||
| 	false, /* 149 */ |  | ||||||
| 	false, /* 150 */ |  | ||||||
| 	false, /* 151 */ |  | ||||||
| 	false, /* 152 */ |  | ||||||
| 	false, /* 153 */ |  | ||||||
| 	false, /* 154 */ |  | ||||||
| 	false, /* 155 */ |  | ||||||
| 	false, /* 156 */ |  | ||||||
| 	false, /* 157 */ |  | ||||||
| 	false, /* 158 */ |  | ||||||
| 	false, /* 159 */ |  | ||||||
| 	false, /* 160 */ |  | ||||||
| 	false, /* 161 */ |  | ||||||
| 	false, /* 162 */ |  | ||||||
| 	false, /* 163 */ |  | ||||||
| 	false, /* 164 */ |  | ||||||
| 	false, /* 165 */ |  | ||||||
| 	false, /* 166 */ |  | ||||||
| 	false, /* 167 */ |  | ||||||
| 	false, /* 168 */ |  | ||||||
| 	false, /* 169 */ |  | ||||||
| 	false, /* 170 */ |  | ||||||
| 	false, /* 171 */ |  | ||||||
| 	false, /* 172 */ |  | ||||||
| 	false, /* 173 */ |  | ||||||
| 	false, /* 174 */ |  | ||||||
| 	false, /* 175 */ |  | ||||||
| 	false, /* 176 */ |  | ||||||
| 	false, /* 177 */ |  | ||||||
| 	false, /* 178 */ |  | ||||||
| 	false, /* 179 */ |  | ||||||
| 	false, /* 180 */ |  | ||||||
| 	false, /* 181 */ |  | ||||||
| 	false, /* 182 */ |  | ||||||
| 	false, /* 183 */ |  | ||||||
| 	false, /* 184 */ |  | ||||||
| 	false, /* 185 */ |  | ||||||
| 	false, /* 186 */ |  | ||||||
| 	false, /* 187 */ |  | ||||||
| 	false, /* 188 */ |  | ||||||
| 	false, /* 189 */ |  | ||||||
| 	false, /* 190 */ |  | ||||||
| 	false, /* 191 */ |  | ||||||
| 	false, /* 192 */ |  | ||||||
| 	false, /* 193 */ |  | ||||||
| 	false, /* 194 */ |  | ||||||
| 	false, /* 195 */ |  | ||||||
| 	false, /* 196 */ |  | ||||||
| 	false, /* 197 */ |  | ||||||
| 	false, /* 198 */ |  | ||||||
| 	false, /* 199 */ |  | ||||||
| 	false, /* 200 */ |  | ||||||
| 	false, /* 201 */ |  | ||||||
| 	false, /* 202 */ |  | ||||||
| 	false, /* 203 */ |  | ||||||
| 	false, /* 204 */ |  | ||||||
| 	false, /* 205 */ |  | ||||||
| 	false, /* 206 */ |  | ||||||
| 	false, /* 207 */ |  | ||||||
| 	false, /* 208 */ |  | ||||||
| 	false, /* 209 */ |  | ||||||
| 	false, /* 210 */ |  | ||||||
| 	false, /* 211 */ |  | ||||||
| 	false, /* 212 */ |  | ||||||
| 	false, /* 213 */ |  | ||||||
| 	false, /* 214 */ |  | ||||||
| 	false, /* 215 */ |  | ||||||
| 	false, /* 216 */ |  | ||||||
| 	false, /* 217 */ |  | ||||||
| 	false, /* 218 */ |  | ||||||
| 	false, /* 219 */ |  | ||||||
| 	false, /* 220 */ |  | ||||||
| 	false, /* 221 */ |  | ||||||
| 	false, /* 222 */ |  | ||||||
| 	false, /* 223 */ |  | ||||||
| 	false, /* 224 */ |  | ||||||
| 	false, /* 225 */ |  | ||||||
| 	false, /* 226 */ |  | ||||||
| 	false, /* 227 */ |  | ||||||
| 	false, /* 228 */ |  | ||||||
| 	false, /* 229 */ |  | ||||||
| 	false, /* 230 */ |  | ||||||
| 	false, /* 231 */ |  | ||||||
| 	false, /* 232 */ |  | ||||||
| 	false, /* 233 */ |  | ||||||
| 	false, /* 234 */ |  | ||||||
| 	false, /* 235 */ |  | ||||||
| 	false, /* 236 */ |  | ||||||
| 	false, /* 237 */ |  | ||||||
| 	false, /* 238 */ |  | ||||||
| 	false, /* 239 */ |  | ||||||
| 	false, /* 240 */ |  | ||||||
| 	false, /* 241 */ |  | ||||||
| 	false, /* 242 */ |  | ||||||
| 	false, /* 243 */ |  | ||||||
| 	false, /* 244 */ |  | ||||||
| 	false, /* 245 */ |  | ||||||
| 	false, /* 246 */ |  | ||||||
| 	false, /* 247 */ |  | ||||||
| 	false, /* 248 */ |  | ||||||
| 	false, /* 249 */ |  | ||||||
| 	false, /* 250 */ |  | ||||||
| 	false, /* 251 */ |  | ||||||
| 	false, /* 252 */ |  | ||||||
| 	false, /* 253 */ |  | ||||||
| 	false, /* 254 */ |  | ||||||
| 	false, /* 255 */ |  | ||||||
| } |  | ||||||
							
								
								
									
										34
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,34 +0,0 @@ | |||||||
| /** |  | ||||||
|  *  Copyright 2014 Paul Querna |  | ||||||
|  * |  | ||||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *  you may not use this file except in compliance with the License. |  | ||||||
|  *  You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *  Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *  See the License for the specific language governing permissions and |  | ||||||
|  *  limitations under the License. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package v1 |  | ||||||
|  |  | ||||||
| func scanString(s []byte, j int) (int, byte) { |  | ||||||
| 	for { |  | ||||||
| 		if j >= len(s) { |  | ||||||
| 			return j, 0 |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		c := s[j] |  | ||||||
| 		j++ |  | ||||||
| 		if byteLookupTable[c]&sliceStringMask == 0 { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return j, c |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user