-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathframe.go
53 lines (46 loc) · 1.3 KB
/
frame.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
package smux
import (
"encoding/binary"
"math"
)
type Frame []byte
func packing(id uint32, b []byte, seal bool) []Frame {
numFrames := int(math.Ceil(float64(len(b)) / float64(NUM_BYTES_MAX_PAYLOAD)))
frames := make([]Frame, numFrames)
for i := 0; i < numFrames; i++ {
length := NUM_BYTES_MAX_PAYLOAD
typ := TYPE_DATA
flag := FLAG_DATA_NONE
if i == numFrames-1 {
length = len(b) - (i * NUM_BYTES_MAX_PAYLOAD)
if seal {
flag = FLAG_DATA_END_STREAM
}
}
frame := make([]byte, NUM_BYTES_HEADER+length)
binary.BigEndian.PutUint16(frame[0:2], uint16(length))
frame[2] = uint8(typ)
frame[3] = uint8(flag)
binary.BigEndian.PutUint32(frame[4:8], id)
payload := b[i*NUM_BYTES_MAX_PAYLOAD : i*NUM_BYTES_MAX_PAYLOAD+length]
for j, _ := range payload {
frame[NUM_BYTES_HEADER+j] = payload[j]
}
frames[i] = frame
}
return frames
}
func sealing(id uint32) Frame {
frame := make(Frame, NUM_BYTES_HEADER)
binary.BigEndian.PutUint16(frame[0:2], uint16(0))
frame[2] = uint8(TYPE_DATA)
frame[3] = uint8(FLAG_DATA_END_STREAM)
binary.BigEndian.PutUint32(frame[4:8], id)
return frame
}
func parseHeader(b []byte) (uint16, uint8, uint8, uint32) {
return binary.BigEndian.Uint16(b[0:2]), // length
uint8(b[2]), // type
uint8(b[3]), // flag
binary.BigEndian.Uint32(b[4:]) // stream id
}