6
6
7
7
package bson
8
8
9
- import "bufio"
9
+ import (
10
+ "bufio"
11
+ )
10
12
11
13
// streamingValueReader reads from an ioReader wrapped in a bufio.Reader. It
12
14
// first reads the BSON length header, then ensures it only ever reads exactly
@@ -15,43 +17,76 @@ import "bufio"
15
17
// Note: this approach trades memory usage for extra buffering and reader calls,
16
18
// so it is less performanted than the in-memory bufferedValueReader.
17
19
type streamingValueReader struct {
18
- br * bufio.Reader
20
+ br * bufio.Reader
21
+ offset int64 // offset is the current read position in the buffer
19
22
}
20
23
21
24
var _ valueReaderByteSrc = (* streamingValueReader )(nil )
22
25
23
- // Read reads up to len(p) bytes from buf[offset:] into p, advancing offset.
24
- func (b * streamingValueReader ) Read ([]byte ) (n int , err error ) {
25
- panic ("Read not implemented for streamingValueReader" )
26
- }
27
-
28
26
// ReadByte returns the single byte at buf[offset] and advances offset by 1.
29
- func (b * streamingValueReader ) ReadByte () (byte , error ) {
30
- panic ("ReadByte not implemented for streamingValueReader" )
27
+ func (s * streamingValueReader ) ReadByte () (byte , error ) {
28
+ c , err := s .br .ReadByte ()
29
+ if err == nil {
30
+ s .offset ++
31
+ }
32
+ return c , err
31
33
}
32
34
33
35
// peek returns buf[offset:offset+n] without advancing offset.
34
- func (b * streamingValueReader ) peek (int ) ([]byte , error ) {
35
- panic ( "peek not implemented for streamingValueReader" )
36
+ func (s * streamingValueReader ) peek (n int ) ([]byte , error ) {
37
+ return s . br . Peek ( n )
36
38
}
37
39
38
40
// discard advances offset by n bytes, returning the number of bytes discarded.
39
- func (b * streamingValueReader ) discard (int ) (int , error ) {
40
- panic ("discard not implemented for streamingValueReader" )
41
+ func (s * streamingValueReader ) discard (n int ) (int , error ) {
42
+ m , err := s .br .Discard (n )
43
+ s .offset += int64 (m )
44
+ return m , err
41
45
}
42
46
43
47
// readSlice scans buf[offset:] for the first occurrence of delim, returns
44
48
// buf[offset:idx+1], and advances offset past it; errors if delim not found.
45
- func (b * streamingValueReader ) readSlice (byte ) ([]byte , error ) {
46
- panic ("readSlice not implemented for streamingValueReader" )
49
+ func (s * streamingValueReader ) readSlice (delim byte ) ([]byte , error ) {
50
+ data , err := s .br .ReadSlice (delim )
51
+ if err != nil {
52
+ return nil , err
53
+ }
54
+ s .offset += int64 (len (data ))
55
+ return data , nil
47
56
}
48
57
49
58
// pos returns the current read position in the buffer.
50
- func (b * streamingValueReader ) pos () int64 {
51
- panic ( "pos not implemented for streamingValueReader" )
59
+ func (s * streamingValueReader ) pos () int64 {
60
+ return s . offset
52
61
}
53
62
54
63
// regexLength will return the total byte length of a BSON regex value.
55
- func (b * streamingValueReader ) regexLength () (int32 , error ) {
56
- panic ("regexLength not implemented for streamingValueReader" )
64
+ func (s * streamingValueReader ) regexLength () (int32 , error ) {
65
+ var (
66
+ count int32
67
+ nulCount int
68
+ )
69
+
70
+ for nulCount < 2 {
71
+ buf , err := s .br .Peek (int (count ) + 1 )
72
+ if err != nil {
73
+ return 0 , err
74
+ }
75
+
76
+ b := buf [count ]
77
+ count ++
78
+ if b == 0x00 {
79
+ nulCount ++
80
+ }
81
+ }
82
+
83
+ return count , nil
84
+ }
85
+
86
+ func (* streamingValueReader ) streamable () bool {
87
+ return true
88
+ }
89
+
90
+ func (s * streamingValueReader ) reset () {
91
+ s .offset = 0
57
92
}
0 commit comments