1/* 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package thrift 18 19import ( 20 "math" 21 "strconv" 22) 23 24type Numeric interface { 25 Int64() int64 26 Int32() int32 27 Int16() int16 28 Byte() byte 29 Int() int 30 Float64() float64 31 Float32() float32 32 String() string 33 isNull() bool 34} 35 36type numeric struct { 37 iValue int64 38 dValue float64 39 sValue string 40 isNil bool 41} 42 43var ( 44 INFINITY Numeric = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false} 45 NEGATIVE_INFINITY Numeric = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false} 46 NAN Numeric = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false} 47 ZERO Numeric = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false} 48 NUMERIC_NULL Numeric = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true} 49) 50 51func NewNumericFromDouble(dValue float64) Numeric { 52 if math.IsInf(dValue, 1) { 53 return INFINITY 54 } 55 if math.IsInf(dValue, -1) { 56 return NEGATIVE_INFINITY 57 } 58 if math.IsNaN(dValue) { 59 return NAN 60 } 61 iValue := int64(dValue) 62 sValue := strconv.FormatFloat(dValue, 'g', 10, 64) 63 isNil := false 64 return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} 65} 66 67func NewNumericFromFloat(dValue float32) Numeric { 68 if math.IsInf(float64(dValue), 1) { 69 return INFINITY 70 } 71 if math.IsInf(float64(dValue), -1) { 72 return NEGATIVE_INFINITY 73 } 74 if math.IsNaN(float64(dValue)) { 75 return NAN 76 } 77 iValue := int32(dValue) 78 sValue := strconv.FormatFloat(float64(dValue), 'g', 10, 32) 79 isNil := false 80 return &numeric{iValue: int64(iValue), dValue: float64(dValue), sValue: sValue, isNil: isNil} 81} 82 83func NewNumericFromI64(iValue int64) Numeric { 84 dValue := float64(iValue) 85 sValue := strconv.FormatInt(iValue, 10) 86 isNil := false 87 return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} 88} 89 90func NewNumericFromI32(iValue int32) Numeric { 91 dValue := float64(iValue) 92 sValue := string(iValue) 93 isNil := false 94 return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil} 95} 96 97func NewNumericFromString(sValue string) Numeric { 98 if sValue == INFINITY.String() { 99 return INFINITY 100 } 101 if sValue == NEGATIVE_INFINITY.String() { 102 return NEGATIVE_INFINITY 103 } 104 if sValue == NAN.String() { 105 return NAN 106 } 107 iValue, _ := strconv.ParseInt(sValue, 10, 64) 108 dValue, _ := strconv.ParseFloat(sValue, 64) 109 isNil := len(sValue) == 0 110 return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} 111} 112 113func NewNumericFromJSONString(sValue string, isNull bool) Numeric { 114 if isNull { 115 return NewNullNumeric() 116 } 117 if sValue == JSON_INFINITY { 118 return INFINITY 119 } 120 if sValue == JSON_NEGATIVE_INFINITY { 121 return NEGATIVE_INFINITY 122 } 123 if sValue == JSON_NAN { 124 return NAN 125 } 126 iValue, _ := strconv.ParseInt(sValue, 10, 64) 127 dValue, _ := strconv.ParseFloat(sValue, 64) 128 return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull} 129} 130 131func NewNullNumeric() Numeric { 132 return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true} 133} 134 135func (p *numeric) Int64() int64 { 136 return p.iValue 137} 138 139func (p *numeric) Int32() int32 { 140 return int32(p.iValue) 141} 142 143func (p *numeric) Int16() int16 { 144 return int16(p.iValue) 145} 146 147func (p *numeric) Byte() byte { 148 return byte(p.iValue) 149} 150 151func (p *numeric) Int() int { 152 return int(p.iValue) 153} 154 155func (p *numeric) Float64() float64 { 156 return p.dValue 157} 158 159func (p *numeric) Float32() float32 { 160 return float32(p.dValue) 161} 162 163func (p *numeric) String() string { 164 return p.sValue 165} 166 167func (p *numeric) isNull() bool { 168 return p.isNil 169} 170