@@ -21,6 +21,8 @@ type Blob struct {
21
21
bytes int64
22
22
offset int64
23
23
handle uint32
24
+ bufptr uint32
25
+ buflen int64
24
26
}
25
27
26
28
var _ io.ReadWriteSeeker = & Blob {}
@@ -66,7 +68,7 @@ func (b *Blob) Close() error {
66
68
}
67
69
68
70
r := b .c .call ("sqlite3_blob_close" , uint64 (b .handle ))
69
-
71
+ b . c . free ( b . bufptr )
70
72
b .handle = 0
71
73
return b .c .error (r )
72
74
}
@@ -86,17 +88,18 @@ func (b *Blob) Read(p []byte) (n int, err error) {
86
88
return 0 , io .EOF
87
89
}
88
90
89
- avail := b .bytes - b .offset
90
91
want := int64 (len (p ))
92
+ avail := b .bytes - b .offset
91
93
if want > avail {
92
94
want = avail
93
95
}
94
-
95
- defer b .c .arena .mark ()()
96
- ptr := b .c .arena .new (uint64 (want ))
96
+ if want > b .buflen {
97
+ b .bufptr = b .c .realloc (b .bufptr , uint64 (want ))
98
+ b .buflen = want
99
+ }
97
100
98
101
r := b .c .call ("sqlite3_blob_read" , uint64 (b .handle ),
99
- uint64 (ptr ), uint64 (want ), uint64 (b .offset ))
102
+ uint64 (b . bufptr ), uint64 (want ), uint64 (b .offset ))
100
103
err = b .c .error (r )
101
104
if err != nil {
102
105
return 0 , err
@@ -106,7 +109,7 @@ func (b *Blob) Read(p []byte) (n int, err error) {
106
109
err = io .EOF
107
110
}
108
111
109
- copy (p , util .View (b .c .mod , ptr , uint64 (want )))
112
+ copy (p , util .View (b .c .mod , b . bufptr , uint64 (want )))
110
113
return int (want ), err
111
114
}
112
115
@@ -123,19 +126,20 @@ func (b *Blob) WriteTo(w io.Writer) (n int64, err error) {
123
126
if want > avail {
124
127
want = avail
125
128
}
126
-
127
- defer b .c .arena .mark ()()
128
- ptr := b .c .arena .new (uint64 (want ))
129
+ if want > b .buflen {
130
+ b .bufptr = b .c .realloc (b .bufptr , uint64 (want ))
131
+ b .buflen = want
132
+ }
129
133
130
134
for want > 0 {
131
135
r := b .c .call ("sqlite3_blob_read" , uint64 (b .handle ),
132
- uint64 (ptr ), uint64 (want ), uint64 (b .offset ))
136
+ uint64 (b . bufptr ), uint64 (want ), uint64 (b .offset ))
133
137
err = b .c .error (r )
134
138
if err != nil {
135
139
return n , err
136
140
}
137
141
138
- mem := util .View (b .c .mod , ptr , uint64 (want ))
142
+ mem := util .View (b .c .mod , b . bufptr , uint64 (want ))
139
143
m , err := w .Write (mem [:want ])
140
144
b .offset += int64 (m )
141
145
n += int64 (m )
@@ -159,11 +163,15 @@ func (b *Blob) WriteTo(w io.Writer) (n int64, err error) {
159
163
//
160
164
// https://sqlite.org/c3ref/blob_write.html
161
165
func (b * Blob ) Write (p []byte ) (n int , err error ) {
162
- defer b .c .arena .mark ()()
163
- ptr := b .c .arena .bytes (p )
166
+ want := int64 (len (p ))
167
+ if want > b .buflen {
168
+ b .bufptr = b .c .realloc (b .bufptr , uint64 (want ))
169
+ b .buflen = want
170
+ }
171
+ util .WriteBytes (b .c .mod , b .bufptr , p )
164
172
165
173
r := b .c .call ("sqlite3_blob_write" , uint64 (b .handle ),
166
- uint64 (ptr ), uint64 (len ( p ) ), uint64 (b .offset ))
174
+ uint64 (b . bufptr ), uint64 (want ), uint64 (b .offset ))
167
175
err = b .c .error (r )
168
176
if err != nil {
169
177
return 0 , err
@@ -187,16 +195,17 @@ func (b *Blob) ReadFrom(r io.Reader) (n int64, err error) {
187
195
if want < 1 {
188
196
want = 1
189
197
}
190
-
191
- defer b .c .arena .mark ()()
192
- ptr := b .c .arena .new (uint64 (want ))
198
+ if want > b .buflen {
199
+ b .bufptr = b .c .realloc (b .bufptr , uint64 (want ))
200
+ b .buflen = want
201
+ }
193
202
194
203
for {
195
- mem := util .View (b .c .mod , ptr , uint64 (want ))
204
+ mem := util .View (b .c .mod , b . bufptr , uint64 (want ))
196
205
m , err := r .Read (mem [:want ])
197
206
if m > 0 {
198
207
r := b .c .call ("sqlite3_blob_write" , uint64 (b .handle ),
199
- uint64 (ptr ), uint64 (m ), uint64 (b .offset ))
208
+ uint64 (b . bufptr ), uint64 (m ), uint64 (b .offset ))
200
209
err := b .c .error (r )
201
210
if err != nil {
202
211
return n , err
0 commit comments