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