Skip to content

Commit 782b626

Browse files
committed
msgpack: add string() for decimal
Added a decimal type conversion function to a string, added tests for this function. Fixed buffer for int64. Added #322
1 parent afca615 commit 782b626

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

decimal/decimal.go

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ func (d Decimal) String() string {
179179
// StringFromInt64 is an internal method for converting int64
180180
// and scale to a string (for numbers up to 19 digits)
181181
func (d Decimal) stringFromInt64(value int64, scale int) string {
182-
var buf [32]byte
182+
183+
var buf [48]byte
183184
pos := 0
184185

185186
negative := value < 0
@@ -196,12 +197,21 @@ func (d Decimal) stringFromInt64(value int64, scale int) string {
196197
length := len(str)
197198

198199
if scale == 0 {
200+
if pos+length > len(buf) {
201+
return d.Decimal.String()
202+
}
199203
copy(buf[pos:], str)
200204
pos += length
201205
return string(buf[:pos])
202206
}
203207

204208
if scale >= length {
209+
210+
required := 2 + (scale - length) + length
211+
if pos+required > len(buf) {
212+
return d.Decimal.String()
213+
}
214+
205215
buf[pos] = '0'
206216
buf[pos+1] = '.'
207217
pos += 2
@@ -215,42 +225,54 @@ func (d Decimal) stringFromInt64(value int64, scale int) string {
215225
copy(buf[pos:], str)
216226
pos += length
217227
} else {
228+
218229
integerLen := length - scale
230+
231+
required := integerLen + 1 + scale
232+
if pos+required > len(buf) {
233+
return d.Decimal.String()
234+
}
235+
219236
copy(buf[pos:], str[:integerLen])
220237
pos += integerLen
221238

222-
fractionalPart := str[integerLen:]
223-
224-
fractionalPart = strings.TrimRight(fractionalPart, "0")
239+
buf[pos] = '.'
240+
pos++
225241

226-
if len(fractionalPart) > 0 {
227-
buf[pos] = '.'
228-
pos++
229-
copy(buf[pos:], fractionalPart)
230-
pos += len(fractionalPart)
231-
}
242+
copy(buf[pos:], str[integerLen:])
243+
pos += scale
232244
}
233245

234246
return string(buf[:pos])
235247
}
236-
237248
func (d Decimal) handleMinInt64(scale int) string {
238-
239249
const minInt64Str = "9223372036854775808"
240250

241-
if scale == 0 {
242-
return "-" + minInt64Str
243-
}
244-
245-
var buf [32]byte
251+
var buf [48]byte
246252
pos := 0
247253

248254
buf[pos] = '-'
249255
pos++
250256

251257
length := len(minInt64Str)
252258

259+
if scale == 0 {
260+
if pos+length > len(buf) {
261+
return "-" + minInt64Str // Fallback.
262+
}
263+
copy(buf[pos:], minInt64Str)
264+
pos += length
265+
return string(buf[:pos])
266+
}
267+
253268
if scale >= length {
269+
required := 2 + (scale - length) + length
270+
if pos+required > len(buf) {
271+
// Fallback.
272+
result := "0." + strings.Repeat("0", scale-length) + minInt64Str
273+
return "-" + result
274+
}
275+
254276
buf[pos] = '0'
255277
buf[pos+1] = '.'
256278
pos += 2
@@ -265,6 +287,11 @@ func (d Decimal) handleMinInt64(scale int) string {
265287
pos += length
266288
} else {
267289
integerLen := length - scale
290+
required := integerLen + 1 + scale
291+
if pos+required > len(buf) {
292+
return d.Decimal.String() // Fallback
293+
}
294+
268295
copy(buf[pos:], minInt64Str[:integerLen])
269296
pos += integerLen
270297

0 commit comments

Comments
 (0)