Skip to content

Commit

Permalink
wire: Export var length string serialization funcs.
Browse files Browse the repository at this point in the history
This commit exports the ReadVarString and WriteVarString functions so
they are available for callers to use.

A variable length string is encoded as a variable length integer
containing the length of the string followed by the bytes that represent
the string itself.
  • Loading branch information
davecgh authored and jrick committed Feb 29, 2016
1 parent 38ff4bb commit 3a30ba7
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 54 deletions.
8 changes: 4 additions & 4 deletions wire/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func BenchmarkReadVarInt9(b *testing.B) {
func BenchmarkReadVarStr4(b *testing.B) {
buf := []byte{0x04, 't', 'e', 's', 't'}
for i := 0; i < b.N; i++ {
readVarString(bytes.NewReader(buf), 0)
ReadVarString(bytes.NewReader(buf), 0)
}
}

Expand All @@ -199,23 +199,23 @@ func BenchmarkReadVarStr4(b *testing.B) {
func BenchmarkReadVarStr10(b *testing.B) {
buf := []byte{0x0a, 't', 'e', 's', 't', '0', '1', '2', '3', '4', '5'}
for i := 0; i < b.N; i++ {
readVarString(bytes.NewReader(buf), 0)
ReadVarString(bytes.NewReader(buf), 0)
}
}

// BenchmarkWriteVarStr4 performs a benchmark on how long it takes to write a
// four byte variable length string.
func BenchmarkWriteVarStr4(b *testing.B) {
for i := 0; i < b.N; i++ {
writeVarString(ioutil.Discard, 0, "test")
WriteVarString(ioutil.Discard, 0, "test")
}
}

// BenchmarkWriteVarStr10 performs a benchmark on how long it takes to write a
// ten byte variable length string.
func BenchmarkWriteVarStr10(b *testing.B) {
for i := 0; i < b.N; i++ {
writeVarString(ioutil.Discard, 0, "test012345")
WriteVarString(ioutil.Discard, 0, "test012345")
}
}

Expand Down
24 changes: 12 additions & 12 deletions wire/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,13 @@ func VarIntSerializeSize(val uint64) int {
return 9
}

// readVarString reads a variable length string from r and returns it as a Go
// string. A varString is encoded as a varInt containing the length of the
// string, and the bytes that represent the string itself. An error is returned
// if the length is greater than the maximum block payload size, since it would
// not be possible to put a varString of that size into a block anyways and it
// also helps protect against memory exhaustion attacks and forced panics
// through malformed messages.
func readVarString(r io.Reader, pver uint32) (string, error) {
// ReadVarString reads a variable length string from r and returns it as a Go
// string. A variable length string is encoded as a variable length integer
// containing the length of the string followed by the bytes that represent the
// string itself. An error is returned if the length is greater than the
// maximum block payload size since it helps protect against memory exhaustion
// attacks and forced panics through malformed messages.
func ReadVarString(r io.Reader, pver uint32) (string, error) {
count, err := readVarInt(r, pver)
if err != nil {
return "", err
Expand All @@ -476,7 +475,7 @@ func readVarString(r io.Reader, pver uint32) (string, error) {
if count > MaxMessagePayload {
str := fmt.Sprintf("variable length string is too long "+
"[count %d, max %d]", count, MaxMessagePayload)
return "", messageError("readVarString", str)
return "", messageError("ReadVarString", str)
}

buf := make([]byte, count)
Expand All @@ -487,9 +486,10 @@ func readVarString(r io.Reader, pver uint32) (string, error) {
return string(buf), nil
}

// writeVarString serializes str to w as a varInt containing the length of the
// string followed by the bytes that represent the string itself.
func writeVarString(w io.Writer, pver uint32, str string) error {
// WriteVarString serializes str to w as a variable length integer containing
// the length of the string followed by the bytes that represent the string
// itself.
func WriteVarString(w io.Writer, pver uint32, str string) error {
err := writeVarInt(w, pver, uint64(len(str)))
if err != nil {
return err
Expand Down
24 changes: 12 additions & 12 deletions wire/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,26 +474,26 @@ func TestVarStringWire(t *testing.T) {
for i, test := range tests {
// Encode to wire format.
var buf bytes.Buffer
err := wire.TstWriteVarString(&buf, test.pver, test.in)
err := wire.WriteVarString(&buf, test.pver, test.in)
if err != nil {
t.Errorf("writeVarString #%d error %v", i, err)
t.Errorf("WriteVarString #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("writeVarString #%d\n got: %s want: %s", i,
t.Errorf("WriteVarString #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}

// Decode from wire format.
rbuf := bytes.NewReader(test.buf)
val, err := wire.TstReadVarString(rbuf, test.pver)
val, err := wire.ReadVarString(rbuf, test.pver)
if err != nil {
t.Errorf("readVarString #%d error %v", i, err)
t.Errorf("ReadVarString #%d error %v", i, err)
continue
}
if val != test.out {
t.Errorf("readVarString #%d\n got: %s want: %s", i,
t.Errorf("ReadVarString #%d\n got: %s want: %s", i,
val, test.out)
continue
}
Expand Down Expand Up @@ -529,18 +529,18 @@ func TestVarStringWireErrors(t *testing.T) {
for i, test := range tests {
// Encode to wire format.
w := newFixedWriter(test.max)
err := wire.TstWriteVarString(w, test.pver, test.in)
err := wire.WriteVarString(w, test.pver, test.in)
if err != test.writeErr {
t.Errorf("writeVarString #%d wrong error got: %v, want: %v",
t.Errorf("WriteVarString #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}

// Decode from wire format.
r := newFixedReader(test.max, test.buf)
_, err = wire.TstReadVarString(r, test.pver)
_, err = wire.ReadVarString(r, test.pver)
if err != test.readErr {
t.Errorf("readVarString #%d wrong error got: %v, want: %v",
t.Errorf("ReadVarString #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
Expand Down Expand Up @@ -569,9 +569,9 @@ func TestVarStringOverflowErrors(t *testing.T) {
for i, test := range tests {
// Decode from wire format.
rbuf := bytes.NewReader(test.buf)
_, err := wire.TstReadVarString(rbuf, test.pver)
_, err := wire.ReadVarString(rbuf, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("readVarString #%d wrong error got: %v, "+
t.Errorf("ReadVarString #%d wrong error got: %v, "+
"want: %v", i, err, reflect.TypeOf(test.err))
continue
}
Expand Down
12 changes: 0 additions & 12 deletions wire/internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,6 @@ func TstWriteVarInt(w io.Writer, pver uint32, val uint64) error {
return writeVarInt(w, pver, val)
}

// TstReadVarString makes the internal readVarString function available to the
// test package.
func TstReadVarString(r io.Reader, pver uint32) (string, error) {
return readVarString(r, pver)
}

// TstWriteVarString makes the internal writeVarString function available to the
// test package.
func TstWriteVarString(w io.Writer, pver uint32, str string) error {
return writeVarString(w, pver, str)
}

// TstReadVarBytes makes the internal readVarBytes function available to the
// test package.
func TstReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32, fieldName string) ([]byte, error) {
Expand Down
16 changes: 8 additions & 8 deletions wire/msgalert.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
return err
}
for i := 0; i < int(count); i++ {
err = writeVarString(w, pver, alert.SetSubVer[i])
err = WriteVarString(w, pver, alert.SetSubVer[i])
if err != nil {
return err
}
Expand All @@ -199,15 +199,15 @@ func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
if err != nil {
return err
}
err = writeVarString(w, pver, alert.Comment)
err = WriteVarString(w, pver, alert.Comment)
if err != nil {
return err
}
err = writeVarString(w, pver, alert.StatusBar)
err = WriteVarString(w, pver, alert.StatusBar)
if err != nil {
return err
}
err = writeVarString(w, pver, alert.Reserved)
err = WriteVarString(w, pver, alert.Reserved)
if err != nil {
return err
}
Expand Down Expand Up @@ -261,7 +261,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
}
alert.SetSubVer = make([]string, count)
for i := 0; i < int(count); i++ {
alert.SetSubVer[i], err = readVarString(r, pver)
alert.SetSubVer[i], err = ReadVarString(r, pver)
if err != nil {
return err
}
Expand All @@ -271,15 +271,15 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
if err != nil {
return err
}
alert.Comment, err = readVarString(r, pver)
alert.Comment, err = ReadVarString(r, pver)
if err != nil {
return err
}
alert.StatusBar, err = readVarString(r, pver)
alert.StatusBar, err = ReadVarString(r, pver)
if err != nil {
return err
}
alert.Reserved, err = readVarString(r, pver)
alert.Reserved, err = ReadVarString(r, pver)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions wire/msgreject.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type MsgReject struct {
// This is part of the Message interface implementation.
func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
// Command that was rejected.
cmd, err := readVarString(r, pver)
cmd, err := ReadVarString(r, pver)
if err != nil {
return err
}
Expand All @@ -90,7 +90,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {

// Human readable string with specific details (over and above the
// reject code above) about why the command was rejected.
reason, err := readVarString(r, pver)
reason, err := ReadVarString(r, pver)
if err != nil {
return err
}
Expand All @@ -112,7 +112,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
// This is part of the Message interface implementation.
func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {
// Command that was rejected.
err := writeVarString(w, pver, msg.Cmd)
err := WriteVarString(w, pver, msg.Cmd)
if err != nil {
return err
}
Expand All @@ -125,7 +125,7 @@ func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {

// Human readable string with specific details (over and above the
// reject code above) about why the command was rejected.
err = writeVarString(w, pver, msg.Reason)
err = WriteVarString(w, pver, msg.Reason)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions wire/msgversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
}
}
if buf.Len() > 0 {
userAgent, err := readVarString(buf, pver)
userAgent, err := ReadVarString(buf, pver)
if err != nil {
return err
}
Expand Down Expand Up @@ -182,7 +182,7 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
return err
}

err = writeVarString(w, pver, msg.UserAgent)
err = WriteVarString(w, pver, msg.UserAgent)
if err != nil {
return err
}
Expand Down

0 comments on commit 3a30ba7

Please sign in to comment.