-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
store.go
66 lines (55 loc) · 1.75 KB
/
store.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
// Copyright (c) Roman Atachiants and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
package tile
import (
"encoding/binary"
"io"
"github.com/kelindar/iostream"
)
const tileDataSize = 54
// WriteTo writes the grid to a specific writer.
func (m *Grid) WriteTo(dst io.Writer) (n int64, err error) {
p1 := At(0, 0)
p2 := At(m.Size.X-1, m.Size.Y-1)
// Write the viewport size
w := iostream.NewWriter(dst)
header := make([]byte, 8)
binary.BigEndian.PutUint16(header[0:2], uint16(p1.X))
binary.BigEndian.PutUint16(header[2:4], uint16(p1.Y))
binary.BigEndian.PutUint16(header[4:6], uint16(p2.X))
binary.BigEndian.PutUint16(header[6:8], uint16(p2.Y))
if _, err := w.Write(header); err != nil {
return w.Offset(), err
}
// Write the grid data
m.pagesWithin(p1, p2, func(page *page) {
if _, err := w.Write(page.Data()); err != nil {
return
}
})
return w.Offset(), nil
}
// ReadFrom reads the grid from the reader.
func ReadFrom(src io.Reader) (grid *Grid, err error) {
r := iostream.NewReader(src)
header := make([]byte, 8)
if _, err := io.ReadFull(r, header); err != nil {
return nil, err
}
// Read the size
var view Rect
view.Min.X = int16(binary.BigEndian.Uint16(header[0:2]))
view.Min.Y = int16(binary.BigEndian.Uint16(header[2:4]))
view.Max.X = int16(binary.BigEndian.Uint16(header[4:6]))
view.Max.Y = int16(binary.BigEndian.Uint16(header[6:8]))
// Allocate a new grid
grid = NewGrid(view.Max.X+1, view.Max.Y+1)
buf := make([]byte, tileDataSize)
grid.pagesWithin(view.Min, view.Max, func(page *page) {
if _, err := io.ReadFull(r, buf); err != nil {
return
}
copy(page.Data(), buf)
})
return
}