...

Source file src/golang.conradwood.net/go-easyops/utils/stream_to_packet.go

Documentation: golang.conradwood.net/go-easyops/utils

     1  package utils
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  )
     7  
     8  type StreamToPacket struct {
     9  	buf              *bytes.Buffer
    10  	start            byte
    11  	esc              byte
    12  	stop             byte
    13  	last_was_escaped bool
    14  	inpacket         bool
    15  	debug            bool
    16  }
    17  
    18  func NewStreamToPacket(start, esc, stop byte) (*StreamToPacket, error) {
    19  	res := &StreamToPacket{
    20  		start: start,
    21  		esc:   esc,
    22  		debug: *debug_packetizer,
    23  		stop:  stop,
    24  		buf:   &bytes.Buffer{},
    25  	}
    26  	res.debugf("New stream packet, start=%c, esc=%c, stop=%c\n", start, esc, stop)
    27  	return res, nil
    28  }
    29  func bdis(b byte) string {
    30  	return fmt.Sprintf("0x%02X (%c)", b, b)
    31  }
    32  
    33  // returns true if a complete packet is in the buf
    34  func (stp *StreamToPacket) AddByte(b byte) bool {
    35  	stp.debugf("adding byte %s (inpacket=%v,last-escaped=%v)\n", bdis(b), stp.inpacket, stp.last_was_escaped)
    36  	if !stp.inpacket {
    37  		// scan for beginning of packet
    38  		if stp.last_was_escaped {
    39  			stp.last_was_escaped = false
    40  			return false
    41  		}
    42  		if b == stp.esc {
    43  			stp.last_was_escaped = true
    44  			return false
    45  		}
    46  		if b != stp.start {
    47  			return false
    48  		}
    49  		stp.inpacket = true
    50  		return false
    51  	}
    52  	// we are in a packet, scan for a new beginning, then we need to restart/resynchronise
    53  	if !stp.last_was_escaped && b == stp.start {
    54  		stp.buf.Reset()
    55  		return false
    56  	}
    57  	if stp.last_was_escaped {
    58  		stp.buf.Write([]byte{b})
    59  		stp.last_was_escaped = false
    60  		return false
    61  	}
    62  	if b == stp.esc {
    63  		stp.last_was_escaped = true
    64  		return false
    65  	}
    66  	// scan for end of packet
    67  	if b == stp.stop {
    68  		return true
    69  	}
    70  	stp.buf.Write([]byte{b})
    71  	return false
    72  }
    73  func (stp *StreamToPacket) ReadPacket() []byte {
    74  	bt := stp.buf.Bytes()
    75  	res := make([]byte, len(bt))
    76  	for i, _ := range bt {
    77  		res[i] = bt[i]
    78  	}
    79  	stp.buf.Reset()
    80  	stp.last_was_escaped = false
    81  	stp.inpacket = false
    82  	stp.debugf("packet read\n")
    83  	return res
    84  }
    85  
    86  func (stp *StreamToPacket) debugf(format string, args ...interface{}) {
    87  	if !stp.debug {
    88  		return
    89  	}
    90  	s := fmt.Sprintf(format, args...)
    91  	fmt.Printf("[streamtopacket] %s", s)
    92  }
    93  

View as plain text