forked from elastos/Elastos.ELA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
header.go
70 lines (57 loc) · 1.42 KB
/
header.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 p2p
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"github.com/elastos/Elastos.ELA/common"
)
type Header struct {
Magic uint32
CMD [CMDSize]byte
Length uint32
Checksum [ChecksumSize]byte
}
func BuildHeader(magic uint32, cmd string, body []byte) *Header {
// Calculate Checksum
checksum := common.Sha256D(body)
header := new(Header)
// Write Magic
header.Magic = magic
// Write CMD
copy(header.CMD[:len(cmd)], cmd)
// Write Length
header.Length = uint32(len(body))
// Write Checksum
copy(header.Checksum[:], checksum[:ChecksumSize])
return header
}
func (header *Header) Verify(buf []byte) error {
// Verify Checksum
sum := common.Sha256D(buf)
checksum := sum[:ChecksumSize]
if !bytes.Equal(header.Checksum[:], checksum) {
return fmt.Errorf("unmatched body checksum")
}
return nil
}
func (header *Header) Serialize() ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.LittleEndian, header)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (header *Header) Deserialize(buf []byte) error {
cmd := buf[CMDOffset : CMDOffset+CMDSize]
end := bytes.IndexByte(cmd, 0)
if end < 0 || end >= CMDSize {
return errors.New("unexpected length of CMD")
}
hdr := bytes.NewReader(buf[:HeaderSize])
return binary.Read(hdr, binary.LittleEndian, header)
}
func (header *Header) GetCMD() string {
return string(bytes.TrimRight(header.CMD[:], string(0)))
}