-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathencoder.go
127 lines (111 loc) · 2.47 KB
/
encoder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package go_engine_io_parser
import (
"bytes"
"encoding/base64"
"io"
)
// Writer writes a frame. It need be Closed before next writing.
type Writer interface {
NextWriter(ft FrameType, pt Type) (io.WriteCloser, error)
}
type writerFeeder interface {
getWriter() (io.Writer, error)
putWriter(error) error
}
type encoder struct {
supportBinary bool
feeder writerFeeder
ft FrameType
pt Type
header bytes.Buffer
frameCache bytes.Buffer
b64Writer io.WriteCloser
rawWriter io.Writer
}
func (e *encoder) Noop() []byte {
if e.supportBinary {
return []byte{0x00, 0x01, 0xff, '6'}
}
return []byte("1:6")
}
func (e *encoder) NextWriter(ft FrameType, pt Type) (io.WriteCloser, error) {
w, err := e.feeder.getWriter()
if err != nil {
return nil, err
}
e.rawWriter = w
e.ft = ft
e.pt = pt
e.frameCache.Reset()
if !e.supportBinary && ft == FrameBinary {
e.b64Writer = base64.NewEncoder(base64.StdEncoding, &e.frameCache)
} else {
e.b64Writer = nil
}
return e, nil
}
func (e *encoder) Write(p []byte) (int, error) {
if e.b64Writer != nil {
return e.b64Writer.Write(p)
}
return e.frameCache.Write(p)
}
func (e *encoder) Close() error {
if e.b64Writer != nil {
e.b64Writer.Close()
}
var writeHeader func() error
if e.supportBinary {
writeHeader = e.writeBinaryHeader
} else {
if e.ft == FrameBinary {
writeHeader = e.writeB64Header
} else {
writeHeader = e.writeTextHeader
}
}
e.header.Reset()
err := writeHeader()
if err == nil {
_, err = e.header.WriteTo(e.rawWriter)
}
if err == nil {
_, err = e.frameCache.WriteTo(e.rawWriter)
}
err = e.feeder.putWriter(err)
return err
}
func (e *encoder) writeTextHeader() error {
l := int64(e.frameCache.Len() + 1) // length for packet type
err := writeTextLen(l, &e.header)
if err == nil {
err = e.header.WriteByte(e.pt.StringByte())
}
return err
}
func (e *encoder) writeB64Header() error {
l := int64(e.frameCache.Len() + 2) // length for 'b' and packet type
err := writeTextLen(l, &e.header)
if err == nil {
err = e.header.WriteByte(BinarySymbol)
}
if err == nil {
err = e.header.WriteByte(e.pt.StringByte())
}
return err
}
func (e *encoder) writeBinaryHeader() error {
l := int64(e.frameCache.Len() + 1) // length for packet type
b := e.pt.StringByte()
if e.ft == FrameBinary {
b = e.pt.Byte()
}
err := e.header.WriteByte(e.ft.Byte())
if err == nil {
err = writeBinaryLen(l, &e.header)
}
if err == nil {
err = e.header.WriteByte(b)
}
return err
}