...
1 package utils
2
3 import (
4 "bytes"
5 "fmt"
6 "io"
7 "sync"
8 )
9
10
28 func NewPacketWriter(r io.Writer, start, escape, stop byte) (*PacketWriter, error) {
29 err := check_valid(start, escape, stop)
30 if err != nil {
31 return nil, err
32 }
33 res := &PacketWriter{
34 start: start,
35 stop: stop,
36 esc: escape,
37 writer: r,
38 }
39 return res, nil
40 }
41
42 type PacketWriter struct {
43 start byte
44 stop byte
45 esc byte
46 writer io.Writer
47 closed bool
48 wrlock sync.Mutex
49 }
50
51 func (pr *PacketWriter) Close() error {
52 pr.closed = true
53 iw, castable := pr.writer.(io.WriteCloser)
54 if castable {
55 err := iw.Close()
56 return err
57 }
58 return nil
59 }
60
61
62 func (pr *PacketWriter) Write(buf []byte) (int, error) {
63 if pr.closed {
64 return 0, fmt.Errorf("write to closed packet writer")
65 }
66 if len(buf) > 8192 {
67 return 0, fmt.Errorf("exceeded max packet size")
68 }
69
70
71 pkt := bytes.Buffer{}
72 pkt.Write([]byte{pr.start})
73 for _, b := range buf {
74 if b == pr.start || b == pr.stop || b == pr.esc {
75 pkt.Write([]byte{pr.esc})
76 }
77 pkt.Write([]byte{b})
78 }
79 pkt.Write([]byte{pr.stop})
80 pktbytes := pkt.Bytes()
81
82 pr.wrlock.Lock()
83 n, err := pr.writer.Write(pktbytes)
84 pr.wrlock.Unlock()
85
86 if err != nil {
87 return n, err
88 }
89 return len(buf), nil
90 }
91
View as plain text