-
Notifications
You must be signed in to change notification settings - Fork 0
/
message.go
70 lines (61 loc) · 1.93 KB
/
message.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
package myrtio
import (
"errors"
)
// ErrWrongHeader is returned when given message contains wrong header codes
var ErrWrongHeader = errors.New("unexpected header codes")
// ErrWrongTail is returned when given message contains wrong tail code
var ErrWrongTail = errors.New("unexpected tail code")
// ErrWrongLength is returned when given message has incorrect length
var ErrWrongLength = errors.New("message length is not correct")
// Message represent MyrtIO message
type Message struct {
Feature byte
Action byte
Payload []byte
}
// Bytes returns message as byte slice
func (m *Message) Bytes() []byte {
var payloadLength = 0
if m.Payload != nil {
payloadLength = len(m.Payload)
}
result := make([]byte, 0, payloadLength+MetaHeaderPadding+1)
result = append(result, FirstHeaderCode, SecondHeaderCode)
result = append(result, byte(payloadLength+2))
result = append(result, m.Feature, m.Action)
if m.Payload != nil && payloadLength > 0 {
result = append(result, m.Payload...)
}
result = append(result, TailCode)
return result
}
// Success checks status value and returns it as bool
func (m *Message) Success() bool {
return m.Payload[0] == SuccessCode
}
// SkipStatus returns payload without first status value
func (m *Message) SkipStatus() []byte {
return m.Payload[1:]
}
// ParseMessage parses message from raw bytes slice
func ParseMessage(message []byte) (*Message, error) {
if len(message) < MinMessageLength || len(message) > MaxMessageLength {
return nil, ErrWrongLength
}
if message[0] != FirstHeaderCode || message[1] != SecondHeaderCode {
return nil, ErrWrongHeader
}
length := message[2]
if len(message) < int(length)+MetaHeaderPadding {
return nil, ErrWrongLength
}
if message[length+MetaHeaderPadding] != TailCode {
return nil, ErrWrongTail
}
return &Message{
Feature: message[MetaHeaderPadding],
Action: message[MetaHeaderPadding+1],
Payload: message[MetaHeaderPadding+2 : MetaHeaderPadding+length],
}, nil
}