in dax/internal/cbor/lexdecimal.go [65:186]
func encode(decimal *Decimal, writer BytesWriter, xormask int) (int, error) {
if decimal.Unscaled().Sign() == 0 {
if err := writer.WriteByte(byte(0x80 ^ xormask)); err != nil {
return 0, err
}
return 1, nil
}
len := 0
precision := precision(decimal)
exponent := precision - int(decimal.scale)
val := decimal.Unscaled()
if val.Sign() < 0 {
if exponent >= -0x3e && exponent < 0x3e {
if err := writer.WriteByte(byte((0x3f - exponent) ^ xormask)); err != nil {
return 0, err
}
len++
} else {
if exponent < 0 {
if err := writer.WriteByte(byte(0x7e ^ xormask)); err != nil {
return 0, err
}
} else {
if err := writer.WriteByte(byte(1 ^ xormask)); err != nil {
return 0, err
}
}
if err := encodeInt32BE(exponent^xormask^0x7fffffff, writer); err != nil {
return 0, err
}
len += 5
}
} else {
if exponent >= -0x3e && exponent < 0x3e {
if err := writer.WriteByte(byte((exponent + 0xc0) ^ xormask)); err != nil {
return 0, err
}
len++
} else {
if exponent < 0 {
if err := writer.WriteByte(byte(0x81 ^ xormask)); err != nil {
return 0, err
}
} else {
if err := writer.WriteByte(byte(0xfe ^ xormask)); err != nil {
return 0, err
}
}
if err := encodeInt32BE(exponent^xormask^0x80000000, writer); err != nil {
return 0, err
}
len += 5
}
}
var terminator int
switch precision % 3 {
case 0:
terminator = 2
case 1:
terminator = 0
val = val.Mul(val, hundred)
case 2:
terminator = 1
val = val.Mul(val, ten)
default:
terminator = 2
}
var digitAdjust int
if val.Sign() >= 0 {
digitAdjust = 12
} else {
digitAdjust = 999 + 12
terminator = 1023 - terminator
}
pos := ((val.BitLen() + 9) / 10) + 1
digits := make([]int, pos)
pos--
digits[pos] = terminator
var rem big.Int
for val.Sign() != 0 {
val.QuoRem(val, thousand, &rem)
pos--
v := int(rem.Int64()) + digitAdjust
if pos < 0 {
digits = append([]int{v}, digits...)
} else {
digits[pos] = v
}
}
accum := 0
var bits uint = 0
for _, v := range digits {
accum = accum<<10 | v
bits += 10
for {
bits -= 8
if err := writer.WriteByte(byte((accum >> bits) ^ xormask)); err != nil {
return 0, err
}
len++
if bits < 8 {
break
}
}
}
if bits != 0 {
if err := writer.WriteByte(byte((accum << uint(8-bits)) ^ xormask)); err != nil {
return 0, err
}
len++
}
return len, nil
}