integrate new bigint encoding into refmt atlas (temporary)
This commit is contained in:
parent
5f31544faa
commit
9f654ab893
@ -17,18 +17,14 @@ import (
|
|||||||
const BigIntMaxSerializedLen = 128 // is this big enough? or too big?
|
const BigIntMaxSerializedLen = 128 // is this big enough? or too big?
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cbor.RegisterCborType(atlas.BuildEntry(BigInt{}).UseTag(2).Transform().
|
cbor.RegisterCborType(atlas.BuildEntry(BigInt{}).Transform().
|
||||||
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
||||||
func(i BigInt) ([]byte, error) {
|
func(i BigInt) ([]byte, error) {
|
||||||
if i.Int == nil {
|
return i.cborBytes(), nil
|
||||||
return []byte{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return i.Bytes(), nil
|
|
||||||
})).
|
})).
|
||||||
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
|
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
|
||||||
func(x []byte) (BigInt, error) {
|
func(x []byte) (BigInt, error) {
|
||||||
return BigFromBytes(x), nil
|
return fromCborBytes(x)
|
||||||
})).
|
})).
|
||||||
Complete())
|
Complete())
|
||||||
}
|
}
|
||||||
@ -117,20 +113,49 @@ func (bi *BigInt) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bi *BigInt) cborBytes() []byte {
|
||||||
|
if bi.Int == nil {
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case bi.Sign() == 0:
|
||||||
|
return []byte{}
|
||||||
|
case bi.Sign() > 0:
|
||||||
|
return append([]byte{0}, bi.Bytes()...)
|
||||||
|
case bi.Sign() < 0:
|
||||||
|
return append([]byte{1}, bi.Bytes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromCborBytes(buf []byte) (BigInt, error) {
|
||||||
|
var negative bool
|
||||||
|
switch buf[0] {
|
||||||
|
case 0:
|
||||||
|
negative = false
|
||||||
|
case 1:
|
||||||
|
negative = true
|
||||||
|
default:
|
||||||
|
return EmptyInt, fmt.Errorf("big int prefix should be either 0 or 1, got %d", buf[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
i := big.NewInt(0).SetBytes(buf[1:])
|
||||||
|
if negative {
|
||||||
|
i.Neg(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return BigInt{i}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (bi *BigInt) MarshalCBOR(w io.Writer) error {
|
func (bi *BigInt) MarshalCBOR(w io.Writer) error {
|
||||||
if bi.Int == nil {
|
if bi.Int == nil {
|
||||||
zero := NewInt(0)
|
zero := NewInt(0)
|
||||||
return zero.MarshalCBOR(w)
|
return zero.MarshalCBOR(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
var enc []byte
|
enc := bi.cborBytes()
|
||||||
switch {
|
|
||||||
case bi.Sign() == 0:
|
|
||||||
case bi.Sign() > 0:
|
|
||||||
enc = append([]byte{0}, bi.Bytes()...)
|
|
||||||
case bi.Sign() < 0:
|
|
||||||
enc = append([]byte{1}, bi.Bytes()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(enc)))
|
header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(enc)))
|
||||||
if _, err := w.Write(header); err != nil {
|
if _, err := w.Write(header); err != nil {
|
||||||
@ -168,20 +193,12 @@ func (bi *BigInt) UnmarshalCBOR(br io.Reader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var negative bool
|
i, err := fromCborBytes(buf)
|
||||||
switch buf[0] {
|
if err != nil {
|
||||||
case 0:
|
return err
|
||||||
negative = false
|
|
||||||
case 1:
|
|
||||||
negative = true
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("big int prefix should be either 0 or 1, got %d", buf[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bi.Int = big.NewInt(0).SetBytes(buf[1:])
|
*bi = i
|
||||||
if negative {
|
|
||||||
bi.Int.Neg(bi.Int)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user