-
Notifications
You must be signed in to change notification settings - Fork 0
/
reader.go
142 lines (124 loc) · 3.12 KB
/
reader.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (C) 2023 by Posit Software, PBC
package rsf
import (
"bufio"
"encoding/binary"
"fmt"
"io"
"math"
)
type rsfReader struct {
pos int
// When reading an RSF file based on a struct, the first entry
// is an index. See `ReadIndex`.
index Index
indexVersion int
// Saves the current position for advancing the reader.
at []string
}
func NewReader() Reader {
return &rsfReader{}
}
func (f *rsfReader) Pos() int {
return f.pos
}
func (f *rsfReader) Seek(pos int, r io.Seeker, fieldNames ...string) error {
i, err := r.Seek(int64(pos), 0)
f.pos = int(i)
f.at = fieldNames
return err
}
func (f *rsfReader) Discard(sz int, r *bufio.Reader, fieldNames ...string) error {
i, err := r.Discard(sz)
if err != nil {
return err
} else if i != sz {
return fmt.Errorf("unexpected discard size %d; expected %d", i, sz)
}
f.pos += i
if len(fieldNames) > 0 {
f.at = fieldNames
}
return nil
}
func (f *rsfReader) ReadSizeField(r io.Reader) (int, error) {
bs := make([]byte, sizeFieldLen)
i, err := io.ReadFull(r, bs)
if err != nil {
return 0, err
} else if i != sizeFieldLen {
return 0, fmt.Errorf("unexpected read size %d; expected %d", i, sizeFieldLen)
}
f.pos += i
sz := binary.LittleEndian.Uint32(bs)
return int(sz), nil
}
func (f *rsfReader) ReadIntField(r io.Reader) (int64, error) {
bs := make([]byte, sizeInt64)
i, err := io.ReadFull(r, bs)
if err != nil {
return 0, err
} else if i != sizeInt64 {
return 0, fmt.Errorf("unexpected read size %d; expected %d", i, sizeInt64)
}
f.pos += i
intVal, _ := binary.Varint(bs)
return intVal, nil
}
func (f *rsfReader) ReadFloatField(r io.Reader) (float64, error) {
bs := make([]byte, sizeFloat64)
i, err := io.ReadFull(r, bs)
if err != nil {
return 0, err
} else if i != sizeFloat64 {
return 0, fmt.Errorf("unexpected read size %d; expected %d", i, sizeFloat64)
}
f.pos += i
return math.Float64frombits(binary.LittleEndian.Uint64(bs)), nil
}
func (f *rsfReader) ReadFixedStringField(sz int, r io.Reader) (string, error) {
// Read string field
bs := make([]byte, sz)
i, err := io.ReadFull(r, bs)
if err != nil {
return "", err
} else if i != sz {
return "", fmt.Errorf("unexpected read size %d; expected %d", i, sz)
}
f.pos += i
return string(bs), nil
}
func (f *rsfReader) ReadStringField(r io.Reader) (string, error) {
// read size
bs := make([]byte, sizeFieldLen)
i, err := io.ReadFull(r, bs)
if err != nil {
return "", err
} else if i != sizeFieldLen {
return "", fmt.Errorf("unexpected read size %d; expected %d", i, sizeFieldLen)
}
f.pos += i
sz := binary.LittleEndian.Uint32(bs)
// Read string field
bs = make([]byte, sz)
i, err = io.ReadFull(r, bs)
if err != nil {
return "", err
} else if i != int(sz) {
return "", fmt.Errorf("unexpected read size %d; expected %d", i, sz)
}
f.pos += i
return string(bs), nil
}
func (f *rsfReader) ReadBoolField(r io.Reader) (bool, error) {
// Read bool field
bs := make([]byte, 1)
i, err := io.ReadFull(r, bs)
if err != nil {
return false, err
} else if i != 1 {
return false, fmt.Errorf("unexpected read size %d; expected %d", i, 1)
}
f.pos += i
return bs[0] == 1, nil
}