-
Notifications
You must be signed in to change notification settings - Fork 0
/
writer.go
128 lines (108 loc) · 2.35 KB
/
writer.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
// Copyright (C) 2023 by Posit Software, PBC
package rsf
import (
"encoding/binary"
"fmt"
"io"
"math"
)
// IndexVersion2 is the first recorded index version. It consists of:
// - NULL
// - backspace
// - ASCII character "2".
var IndexVersion2 = []byte{0x00, 0x08, 0x32}
var (
Version1 = 1
Version2 = 2
)
type rsfWriter struct {
writer io.Writer
version int
pos int
}
func NewWriter(f io.Writer) Writer {
return &rsfWriter{
writer: f,
version: Version1,
}
}
func NewWriterWithVersion(f io.Writer, version int) Writer {
return &rsfWriter{
writer: f,
version: version,
}
}
func (f *rsfWriter) WriteSizeField(pos int, val int, r io.Writer) (int, error) {
// Write size
bs := make([]byte, sizeFieldLen)
binary.LittleEndian.PutUint32(bs, uint32(val))
sz, err := r.Write(bs)
if err != nil {
return 0, err
}
return pos + sz, nil
}
func (f *rsfWriter) WriteInt64Field(pos int, val int64, r io.Writer) (int, error) {
// Write int
bs := make([]byte, sizeInt64)
binary.PutVarint(bs, val)
sz, err := r.Write(bs)
if err != nil {
return 0, err
}
return pos + sz, nil
}
func (f *rsfWriter) WriteFloatField(pos int, val float64, r io.Writer) (int, error) {
// Write float
bs := make([]byte, sizeFloat64)
binary.LittleEndian.PutUint64(bs, math.Float64bits(val))
sz, err := r.Write(bs)
if err != nil {
return 0, err
}
return pos + sz, nil
}
func (f *rsfWriter) WriteFixedStringField(pos, sz int, val string, r io.Writer) (int, error) {
if sz != len(val) {
return 0, fmt.Errorf("size %d does not match expected size %d", len(val), sz)
}
// Write value
i, err := r.Write([]byte(val))
if err != nil {
return 0, err
}
if i != sz {
return 0, fmt.Errorf("expected write size %d; wrote %d", sz, i)
}
return pos + sz, nil
}
func (f *rsfWriter) WriteStringField(pos int, val string, r io.Writer) (int, error) {
// Write size
bs := make([]byte, sizeFieldLen)
binary.LittleEndian.PutUint32(bs, uint32(len(val)))
sz, err := r.Write(bs)
if err != nil {
return 0, err
}
// Write value
i, err := r.Write([]byte(val))
if err != nil {
return 0, err
}
sz += i
return pos + sz, nil
}
func (f *rsfWriter) WriteBoolField(pos int, val bool, r io.Writer) (int, error) {
// Write value
var b []byte
if val {
b = []byte{1}
} else {
b = []byte{0}
}
sz, err := r.Write(b)
if err != nil {
return 0, err
}
return pos + sz, nil
}