/
header.go
127 lines (112 loc) · 2.77 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
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 rexfile
import (
"encoding/binary"
"fmt"
"io"
)
const (
rexFileHeaderSize = 64
rexDataBlockHeaderSize = 16
// Supported block types
typeLineSet = 0
typeText = 1
typePointList = 2
typeMesh = 3
typeImage = 4
typeMaterial = 5
typeSceneNode = 6
typeTrack = 7
)
// Header defines the structure of the REX header
type Header struct {
Magic [4]byte
Version uint16
Crc uint32
NrBlocks uint16
StartAddr uint16
SizeBytes uint64
Reserved [42]byte
}
// DataBlockHeader stores the header information of a data block
type DataBlockHeader struct {
Type uint16
Version uint16
Size uint32 // the Size is the size of the data block w/o the data block header
ID uint64
}
// CreateHeader returns a valid fresh header block
func CreateHeader() *Header {
header := &Header{
Version: 1,
Crc: 0,
NrBlocks: 0,
StartAddr: 86, // fixed CSB of 22 bytes
SizeBytes: 0,
}
header.Magic[0] = 'R'
header.Magic[1] = 'E'
header.Magic[2] = 'X'
header.Magic[3] = '1'
return header
}
// Write converts the REX header and a dummy CSR and writes it to the given writer
func (h *Header) Write(w io.Writer) error {
var header = []interface{}{
h.Magic,
h.Version,
h.Crc,
h.NrBlocks,
h.StartAddr,
h.SizeBytes,
h.Reserved,
// default CSB block
uint32(3876),
uint16(4),
[]byte("EPSG"),
float32(0.0),
float32(0.0),
float32(0.0),
}
for _, v := range header {
err := binary.Write(w, binary.LittleEndian, v)
if err != nil {
return err
}
}
return nil
}
// ReadHeader reads the REX header from a given file
func ReadHeader(r io.Reader) (*Header, error) {
var header Header
if err := binary.Read(r, binary.LittleEndian, &header); err != nil {
return &Header{}, fmt.Errorf("Error during reading header %v", err)
}
// read coordinate system block
var srid uint32
var sz uint16
binary.Read(r, binary.LittleEndian, &srid)
binary.Read(r, binary.LittleEndian, &sz)
name := make([]byte, sz)
binary.Read(r, binary.LittleEndian, &name)
var x, y, z float32
binary.Read(r, binary.LittleEndian, &x)
binary.Read(r, binary.LittleEndian, &y)
binary.Read(r, binary.LittleEndian, &z)
return &header, nil
}
// ReadDataBlockHeader reads a data block header from reader
func ReadDataBlockHeader(r io.Reader) (DataBlockHeader, error) {
var hdr DataBlockHeader
if err := binary.Read(r, binary.LittleEndian, &hdr); err != nil {
return hdr, err
}
return hdr, nil
}
// WriteDataBlockHeader writes the given data block header to the writer
func WriteDataBlockHeader(w io.Writer, hdr DataBlockHeader) error {
return binary.Write(w, binary.LittleEndian, &hdr)
}
// String nicely print header
func (h Header) String() string {
return fmt.Sprintf("REX File (v%d, %d blocks, %d bytes)", h.Version, h.NrBlocks, h.SizeBytes)
}