You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	add lexer
This commit is contained in:
		
							
								
								
									
										48
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,2 +1,50 @@ | ||||
| # go | ||||
| faster than DOM, more usable than SAX/StAX | ||||
|  | ||||
| # string | ||||
|  | ||||
| ``` | ||||
| func Benchmark_jsoniter_string(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		lexer := NewLexerWithArray([]byte(`"\ud83d\udc4a"`)) | ||||
| 		lexer.LexString() | ||||
| 	} | ||||
| } | ||||
| ``` | ||||
|  | ||||
| 10000000	       140 ns/op | ||||
|  | ||||
| ``` | ||||
| func Benchmark_json_string(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		result := "" | ||||
| 		json.Unmarshal([]byte(`"\ud83d\udc4a"`), &result) | ||||
| 	} | ||||
| } | ||||
| ```` | ||||
|  | ||||
| 2000000	       710 ns/op (5x slower) | ||||
|  | ||||
| # int | ||||
|  | ||||
| ``` | ||||
| func Benchmark_jsoniter_int(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		lexer := NewLexerWithArray([]byte(`-100`)) | ||||
| 		lexer.LexInt64() | ||||
| 	} | ||||
| } | ||||
| ``` | ||||
|  | ||||
| 30000000	        60.1 ns/op | ||||
|  | ||||
| ``` | ||||
| func Benchmark_json_int(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		result := int64(0) | ||||
| 		json.Unmarshal([]byte(`-100`), &result) | ||||
| 	} | ||||
| } | ||||
| ``` | ||||
|  | ||||
| 3000000	       505 ns/op (8x slower) | ||||
							
								
								
									
										358
									
								
								jsoniter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								jsoniter.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,358 @@ | ||||
| package jsoniter | ||||
|  | ||||
| import ( | ||||
| 	fflib "github.com/pquerna/ffjson/fflib/v1" | ||||
| 	"strconv" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| 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 { | ||||
| 	ErrorHandler func(error) | ||||
| 	lexer        *fflib.FFLexer | ||||
| } | ||||
|  | ||||
| type UnexpectedToken struct { | ||||
| 	Expected Token | ||||
| 	Actual   Token | ||||
| } | ||||
|  | ||||
| func (err *UnexpectedToken) Error() string { | ||||
| 	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)) { | ||||
| 	lexer := iter.lexer | ||||
| 	if !iter.AssertToken(TokenLeftBrace) { | ||||
| 		return | ||||
| 	} | ||||
| 	index := 0 | ||||
| 	for { | ||||
| 		lexer.Scan() | ||||
| 		callback(iter, index) | ||||
| 		index += 1 | ||||
| 		if iter.Token() != TokenComma { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	iter.AssertToken(TokenRightBrace) | ||||
| 	lexer.Scan() | ||||
| } | ||||
|  | ||||
| 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 | ||||
| 		} | ||||
| 	} | ||||
| 	iter.AssertToken(TokenRightBracket) | ||||
| 	lexer.Scan() | ||||
| } | ||||
|  | ||||
| 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{ | ||||
| 			Expected: expected, | ||||
| 			Actual: actual, | ||||
| 		}) | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (iter Iterator) Token() Token { | ||||
| 	return Token(iter.lexer.Token) | ||||
| } | ||||
|  | ||||
| func (iter *Iterator) OnError(err error) { | ||||
| 	if iter.ErrorHandler == nil { | ||||
| 		panic(err.Error()) | ||||
| 	} else { | ||||
| 		iter.ErrorHandler(err) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										254
									
								
								jsoniter_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								jsoniter_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | ||||
| 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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								lexer.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,276 @@ | ||||
| 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 | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										95
									
								
								lexer_int_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								lexer_int_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| 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) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										83
									
								
								lexer_io_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								lexer_io_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| 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) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										101
									
								
								lexer_string_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								lexer_string_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| package jsoniter | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| func Test_string_empty(t *testing.T) { | ||||
| 	lexer := NewLexer(bytes.NewBufferString(`""`), 4096) | ||||
| 	val, err := lexer.LexString() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if val != "" { | ||||
| 		t.Fatal(val) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_string_hello(t *testing.T) { | ||||
| 	lexer := NewLexer(bytes.NewBufferString(`"hello"`), 4096) | ||||
| 	val, err := lexer.LexString() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if val != "hello" { | ||||
| 		t.Fatal(val) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_string_escape_quote(t *testing.T) { | ||||
| 	lexer := NewLexer(bytes.NewBufferString(`"hel\"lo"`), 4096) | ||||
| 	val, err := lexer.LexString() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if val != `hel"lo` { | ||||
| 		t.Fatal(val) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_string_escape_newline(t *testing.T) { | ||||
| 	lexer := NewLexer(bytes.NewBufferString(`"hel\nlo"`), 4096) | ||||
| 	val, err := lexer.LexString() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if val != "hel\nlo" { | ||||
| 		t.Fatal(val) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_string_escape_unicode(t *testing.T) { | ||||
| 	lexer := NewLexer(bytes.NewBufferString(`"\u4e2d\u6587"`), 4096) | ||||
| 	val, err := lexer.LexString() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if val != "中文" { | ||||
| 		t.Fatal(val) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_string_escape_unicode_with_surrogate(t *testing.T) { | ||||
| 	lexer := NewLexer(bytes.NewBufferString(`"\ud83d\udc4a"`), 4096) | ||||
| 	val, err := lexer.LexString() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if val != "\xf0\x9f\x91\x8a" { | ||||
| 		t.Fatal(val) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Benchmark_jsoniter_unicode(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		lexer := NewLexerWithArray([]byte(`"\ud83d\udc4a"`)) | ||||
| 		lexer.LexString() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Benchmark_jsoniter_ascii(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		lexer := NewLexerWithArray([]byte(`"hello"`)) | ||||
| 		lexer.LexString() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Benchmark_json_unicode(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		result := "" | ||||
| 		json.Unmarshal([]byte(`"\ud83d\udc4a"`), &result) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Benchmark_json_ascii(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		result := "" | ||||
| 		json.Unmarshal([]byte(`"hello"`), &result) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										202
									
								
								vendor/github.com/pquerna/ffjson/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/pquerna/ffjson/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
|  | ||||
|                                  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
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/pquerna/ffjson/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| 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
									
									
										Normal file
									
								
							
							
						
						
									
										421
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,421 @@ | ||||
| // 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
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer_nopool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| // +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
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/buffer_pool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| // 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
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/bytenum.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/decimal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,378 @@ | ||||
| // 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
									
									
										Normal file
									
								
							
							
						
						
									
										668
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/extfloat.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,668 @@ | ||||
| // 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
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/fold.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										542
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/ftoa.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,542 @@ | ||||
| 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
									
									
										Normal file
									
								
							
							
						
						
									
										936
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/atof.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,936 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/atoi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,213 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										668
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,668 @@ | ||||
| // 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
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/internal/ftoa.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,475 @@ | ||||
| // 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
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/iota.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										512
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/jsonstring.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,512 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										1000
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/lexer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										513
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,513 @@ | ||||
| /** | ||||
|  *  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
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /** | ||||
|  *  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