From 8c2176fbf81da275fd2e66f7da607185e5c335c3 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 26 Aug 2019 13:07:21 -0700 Subject: [PATCH] lnwire/features: add EncodeBase32 and DecodeBase32 w/ generic helpers --- lnwire/features.go | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/lnwire/features.go b/lnwire/features.go index 875ef401..e86a69ee 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -169,12 +169,25 @@ func (fv *RawFeatureVector) Encode(w io.Writer) error { return err } + return fv.encode(w, length, 8) +} + +// EncodeBase32 writes the feature vector in base32 representation. Every feature +// encoded as a bit, and the bit vector is serialized using the least number of +// bytes. +func (fv *RawFeatureVector) EncodeBase32(w io.Writer) error { + length := fv.SerializeSize32() + return fv.encode(w, length, 5) +} + +// encode writes the feature vector +func (fv *RawFeatureVector) encode(w io.Writer, length, width int) error { // Generate the data and write it. data := make([]byte, length) for feature := range fv.features { - byteIndex := int(feature / 8) - bitIndex := feature % 8 - data[length-byteIndex-1] |= 1 << bitIndex + byteIndex := int(feature) / width + bitIndex := int(feature) % width + data[length-byteIndex-1] |= 1 << uint(bitIndex) } _, err := w.Write(data) @@ -193,6 +206,19 @@ func (fv *RawFeatureVector) Decode(r io.Reader) error { } length := binary.BigEndian.Uint16(l[:]) + return fv.decode(r, int(length), 8) +} + +// DecodeBase32 reads the feature vector from its base32 representation. Every +// feature encoded as a bit, and the bit vector is serialized using the least +// number of bytes. +func (fv *RawFeatureVector) DecodeBase32(r io.Reader, length int) error { + return fv.decode(r, length, 5) +} + +// decode reads a feature vector from the next length bytes of the io.Reader, +// assuming each byte has width feature bits encoded per byte. +func (fv *RawFeatureVector) decode(r io.Reader, length, width int) error { // Read the feature vector data. data := make([]byte, length) if _, err := io.ReadFull(r, data); err != nil { @@ -200,10 +226,10 @@ func (fv *RawFeatureVector) Decode(r io.Reader) error { } // Set feature bits from parsed data. - bitsNumber := len(data) * 8 + bitsNumber := len(data) * width for i := 0; i < bitsNumber; i++ { - byteIndex := uint16(i / 8) - bitIndex := uint(i % 8) + byteIndex := int(i / width) + bitIndex := uint(i % width) if (data[length-byteIndex-1]>>bitIndex)&1 == 1 { fv.Set(FeatureBit(i)) }