github.com/artyom/thrift@v0.0.0-20130902103359-388840a05deb/numeric.go (about) 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 20 package thrift 21 22 import ( 23 "math" 24 "strconv" 25 ) 26 27 type 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 39 type numeric struct { 40 iValue int64 41 dValue float64 42 sValue string 43 isNil bool 44 } 45 46 var ( 47 INFINITY Numeric 48 NEGATIVE_INFINITY Numeric 49 NAN Numeric 50 ZERO Numeric 51 NUMERIC_NULL Numeric 52 ) 53 54 func 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 70 func NewNumericFromI64(iValue int64) Numeric { 71 dValue := float64(iValue) 72 sValue := string(iValue) 73 isNil := false 74 return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} 75 } 76 77 func NewNumericFromI32(iValue int32) Numeric { 78 dValue := float64(iValue) 79 sValue := string(iValue) 80 isNil := false 81 return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil} 82 } 83 84 func 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 100 func 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 118 func NewNullNumeric() Numeric { 119 return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true} 120 } 121 122 func (p *numeric) Int64() int64 { 123 return p.iValue 124 } 125 126 func (p *numeric) Int32() int32 { 127 return int32(p.iValue) 128 } 129 130 func (p *numeric) Int16() int16 { 131 return int16(p.iValue) 132 } 133 134 func (p *numeric) Byte() byte { 135 return byte(p.iValue) 136 } 137 138 func (p *numeric) Int() int { 139 return int(p.iValue) 140 } 141 142 func (p *numeric) Float64() float64 { 143 return p.dValue 144 } 145 146 func (p *numeric) Float32() float32 { 147 return float32(p.dValue) 148 } 149 150 func (p *numeric) String() string { 151 return p.sValue 152 } 153 154 func (p *numeric) isNull() bool { 155 return p.isNil 156 } 157 158 func 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 }