/
message.go
69 lines (60 loc) · 2.02 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
package message
import (
"errors"
)
var (
// ErrTypeAlreadyDefined is returned when an already defined message type is redefined.
ErrTypeAlreadyDefined = errors.New("message type is already defined")
// ErrUnknownType is returned when a definition for an unknown message type is requested.
ErrUnknownType = errors.New("message type unknown")
)
// Type denotes the byte ID of a given message type.
type Type byte
// Definition describes a message's ID, its max byte length and whether its size can be variable.
type Definition struct {
// ID defines the unique identifier of the message.
ID Type
// MaxBytesLength defines the max byte length of the message type.
// when 0, it means a message can be arbitrary size
MaxBytesLength uint16
// VariableLength defines if the message length is variable.
VariableLength bool
}
// Registry holds message definitions.
type Registry struct {
definitions []*Definition
}
// NewRegistry creates and initializes a new Registry.
// Once it is done, the Registry is immutable.
// Message definitions should be strictly monotonically increasing (based on their Message Type (uint16)).
func NewRegistry(defs []*Definition) *Registry {
if len(defs) == 0 {
panic("can't initialize registry with empty definitions")
}
// create a Registry with room for all definitions
r := &Registry{definitions: make([]*Definition, len(defs))}
for i, def := range defs {
// check order and monotonicity of definitions
if Type(i) != def.ID {
panic("message definitions are inconsistent")
}
// add definition to Registry
r.definitions[def.ID] = def
}
return r
}
// Definitions returns all registered message definitions.
func (r *Registry) Definitions() []*Definition {
return r.definitions
}
// DefinitionForType returns the definition for the given message type.
func (r *Registry) DefinitionForType(msgType Type) (*Definition, error) {
if len(r.definitions)-1 < int(msgType) {
return nil, ErrUnknownType
}
def := r.definitions[msgType]
if def == nil {
return nil, ErrUnknownType
}
return def, nil
}