Skip to content

Commit

Permalink
Support ascii format
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimmy Wong committed Jun 12, 2020
1 parent b796bff commit d8af6a9
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 5 deletions.
68 changes: 67 additions & 1 deletion frame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ func TestFrameConn(t *testing.T) {
return
}
}
fmt.Println(string(b))
if len(string(b)) > 3 {
fmt.Println(string(b))
}
}
}(c)
}
Expand All @@ -70,3 +72,67 @@ func TestFrameConn(t *testing.T) {

time.Sleep(1 * time.Second)
}

func TestFrameConnAsciiFormat(t *testing.T) {
//server
l, err := net.Listen("tcp", ":9983")
if err != nil {
t.Fatal(err)
}
defer l.Close()

encoderConfig := EncoderConfig{
ByteOrder: binary.BigEndian,
LengthFieldLength: 2,
LengthAdjustment: 0,
LengthIncludesLengthFieldLength: false,
Format: ASCII,
}

decoderConfig := DecoderConfig{
ByteOrder: binary.BigEndian,
LengthFieldLength: 2,
LengthFieldOffset: 0,
LengthAdjustment: 0,
InitialBytesToStrip: 2,
Format: ASCII,
}

go func() {
for {
conn, err := l.Accept()
if err != nil {
log.Println(err)
return
}

c := NewLengthFieldBasedFrameConn(encoderConfig, decoderConfig, conn)
go func(conn FrameConn) {
for {
b, err := c.ReadFrame()
if err != nil {
if err == io.EOF {
return
}
}
if len(string(b)) > 3 {
fmt.Println(string(b))
}
}
}(c)
}

}()

conn, err := net.Dial("tcp", "127.0.0.1:9983")
if err != nil {
t.Fatal(err)
}
defer conn.Close()

fc := NewLengthFieldBasedFrameConn(encoderConfig, decoderConfig, conn)
fc.WriteFrame([]byte("hello"))
fc.WriteFrame([]byte("world"))

time.Sleep(1 * time.Second)
}
50 changes: 46 additions & 4 deletions length_field_based_frameconn.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import (
"encoding/binary"
"fmt"
"net"
"strconv"
)

const (
// ASCII is ASCII encoding
ASCII = iota
// BINARY encoding
BINARY
)

type lengthFieldBasedFrameConn struct {
Expand All @@ -25,6 +33,8 @@ type EncoderConfig struct {
LengthAdjustment int
// LengthIncludesLengthFieldLength is true, the length of the prepended length field is added to the value of the prepended length field
LengthIncludesLengthFieldLength bool
// Format is the message length data format
Format int
}

// DecoderConfig config for decoder.
Expand All @@ -39,6 +49,8 @@ type DecoderConfig struct {
LengthAdjustment int
// InitialBytesToStrip is the number of first bytes to strip out from the decoded frame
InitialBytesToStrip int
// Format is the message length data format
Format int
}

// NewLengthFieldBasedFrameConn returns a wrapped Frame conn based on the length field.
Expand Down Expand Up @@ -85,6 +97,16 @@ func (fc *lengthFieldBasedFrameConn) ReadFrame() ([]byte, error) {
}

func (fc *lengthFieldBasedFrameConn) getUnadjustedFrameLength() (lenBuf []byte, n uint64, err error) {
if fc.decoderConfig.Format == ASCII {
lenBuf := make([]byte, fc.decoderConfig.LengthFieldLength)
_, err = fc.r.Read(lenBuf)
i, err := strconv.ParseUint(string(lenBuf), 10, 64)
if err != nil {
return nil, 0, err
}
return lenBuf, i, nil
}
// Default assume format is binary
switch fc.decoderConfig.LengthFieldLength {
case 1:
b, err := fc.r.ReadByte()
Expand Down Expand Up @@ -147,6 +169,9 @@ func (fc *lengthFieldBasedFrameConn) WriteFrame(p []byte) error {
if length >= 256 {
return fmt.Errorf("length does not fit into a byte: %d", length)
}
if fc.encoderConfig.Format == ASCII {
return fmt.Errorf("Ascii format not allowed for LengthFieldLength = 1")
}
err = fc.w.WriteByte(byte(length))
if err != nil {
return err
Expand All @@ -156,7 +181,11 @@ func (fc *lengthFieldBasedFrameConn) WriteFrame(p []byte) error {
return fmt.Errorf("length does not fit into a short integer: %d", length)
}
buf := make([]byte, 2)
fc.encoderConfig.ByteOrder.PutUint16(buf, uint16(length))
if fc.encoderConfig.Format == ASCII {
copy(buf, []byte(fmt.Sprintf("%02d", length)))
} else {
fc.encoderConfig.ByteOrder.PutUint16(buf, uint16(length))
}
_, err = fc.w.Write(buf)
if err != nil {
return err
Expand All @@ -165,21 +194,34 @@ func (fc *lengthFieldBasedFrameConn) WriteFrame(p []byte) error {
if length >= 16777216 {
return fmt.Errorf("length does not fit into a medium integer: %d", length)
}
buf := writeUint24(fc.encoderConfig.ByteOrder, length)
buf := make([]byte, 3)
if fc.encoderConfig.Format == ASCII {
copy(buf, []byte(fmt.Sprintf("%03d", length)))
} else {
buf = writeUint24(fc.encoderConfig.ByteOrder, length)
}
_, err = fc.w.Write(buf)
if err != nil {
return err
}
case 4:
buf := make([]byte, 4)
fc.encoderConfig.ByteOrder.PutUint32(buf, uint32(length))
if fc.encoderConfig.Format == ASCII {
copy(buf, []byte(fmt.Sprintf("%04d", length)))
} else {
fc.encoderConfig.ByteOrder.PutUint32(buf, uint32(length))
}
_, err = fc.w.Write(buf)
if err != nil {
return err
}
case 8:
buf := make([]byte, 8)
fc.encoderConfig.ByteOrder.PutUint64(buf, uint64(length))
if fc.encoderConfig.Format == ASCII {
copy(buf, []byte(fmt.Sprintf("%08d", length)))
} else {
fc.encoderConfig.ByteOrder.PutUint64(buf, uint64(length))
}
_, err = fc.w.Write(buf)
if err != nil {
return err
Expand Down

0 comments on commit d8af6a9

Please sign in to comment.