-
Notifications
You must be signed in to change notification settings - Fork 0
/
packet.go
127 lines (100 loc) · 2.39 KB
/
packet.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 kosuzu
import (
"bytes"
"encoding/binary"
"io"
)
// Packet is a byte sequence
// representing a message
// serialized to be sent
// through network.
type Packet struct {
Opcode int32
dataLength int64
payload []byte
}
// Payload returns the data written
// to the network packet.
func (packet *Packet) Payload() []byte {
payload := make([]byte, len(packet.payload))
copy(payload, packet.payload)
return payload
}
// DataLength returns the length of
// the network packet payload.
func (packet *Packet) DataLength() int64 {
return packet.dataLength
}
// Bytes returns the raw binary representation
// of the packet.
func (packet *Packet) Bytes() ([]byte, error) {
buffer := bytes.NewBuffer(make([]byte,
4+8+packet.dataLength))
buffer.Reset()
_, err := packet.WriteTo(buffer)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
// WriteTo writes the whole contents of
// the packet to the writer stream.
func (packet *Packet) WriteTo(stream io.Writer) (int64, error) {
err := binary.Write(stream,
binary.BigEndian, packet.Opcode)
if err != nil {
return 4, err
}
err = binary.Write(stream,
binary.BigEndian, packet.dataLength)
if err != nil {
return 12, err
}
n, err := stream.Write(packet.payload)
if err != nil {
return int64(n), err
}
return 12 + packet.dataLength, nil
}
// ReadPacketFrom reads a new
// packet from the reader stream.
func ReadPacketFrom(stream io.Reader) (int64, *Packet, error) {
packet := new(Packet)
err := binary.Read(stream,
binary.BigEndian, &packet.Opcode)
if err != nil {
return 4, nil, err
}
err = binary.Read(stream,
binary.BigEndian, &packet.dataLength)
if err != nil {
return 12, nil, err
}
packet.payload = make([]byte, packet.dataLength)
n, err := stream.Read(packet.payload)
if err != nil {
return int64(n), nil, err
}
return 12 + packet.dataLength, packet, nil
}
// PacketFromBytes creates a new packet
// out of the byte sequence.
func PacketFromBytes(data []byte) (*Packet, error) {
buffer := bytes.NewBuffer(data)
_, packet, err := ReadPacketFrom(buffer)
if err != nil {
return nil, err
}
return packet, nil
}
// NewPacket creates a new packet
// with the specified opcode. Opcodes
// are required to identify the type
// of the network packet.
func NewPacket(opcode int32, data []byte) *Packet {
return &Packet{
Opcode: opcode,
dataLength: int64(len(data)),
payload: data,
}
}