-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblob.zig
70 lines (59 loc) · 2.55 KB
/
blob.zig
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
//! Module provides support for Incremental Blob I/O
const c = @import("c.zig").c;
const sqlite3 = @import("sqlite3.zig");
const errors = @import("errors.zig");
/// Blob is a slice of bytes treated as an opaque array,
/// whose structure is interpreted or enforced in any ways.
pub const Blob = []const u8;
/// ZeroBlob is a blob with a fixed length containing only zeroes.
///
/// A ZeroBlob is intended to serve as a placeholder; content can later be written with incremental i/o.
/// See "zeroblob" on https://sqlite.org/c3ref/blob_open.html for more details.
pub const ZeroBlob = struct { len: u64 };
/// ReadWriter is an interface to sqlite3's Incremental Blob I/O
///
/// In practice, it's a reference to sqlite3_blob object.
pub const ReadWriter = opaque {
const Self = @This();
/// Close closes this blob object.
/// The handle is closed unconditionally, ie. even if this routine returns an error code, the handle is still closed.
pub fn close(self: *Self) !void {
const blob = @ptrCast(*c.sqlite3_blob, self);
const ret = c.sqlite3_blob_close(blob);
if (ret != c.SQLITE_OK) {
return errors.from(ret);
}
}
/// Len returns the size in bytes of the blob object.
pub fn len(self: *Self) usize {
const blob = @ptrCast(*c.sqlite3_blob, self);
return @intCast(usize, c.sqlite3_blob_bytes(blob));
}
/// Read reads from the blob at the given offset into the provided buffer.
/// It returns the number of bytes read.
pub fn read(self: *Self, offset: usize, buffer: []u8) errors.Error!usize {
const blob = @ptrCast(*c.sqlite3_blob, self);
if (offset >= self.len()) {
return 0;
}
var tmp = blk: {
const remaining = self.len() - offset;
break :blk if (buffer.len > remaining) buffer[0..remaining] else buffer;
};
const ret = c.sqlite3_blob_read(blob, tmp.ptr, @intCast(c_int, tmp.len), @intCast(c_int, offset));
if (ret != c.SQLITE_OK) {
return errors.from(ret);
}
return tmp.len;
}
/// Write writes to the blob at the given offset from the provided buffer.
/// It returns the number of bytes written.
pub fn write(self: *Self, offset: usize, data: []const u8) errors.Error!usize {
const blob = @ptrCast(*c.sqlite3_blob, self);
const ret = c.sqlite3_blob_write(blob, data.ptr, @intCast(c_int, data.len), @intCast(c_int, offset));
if (ret != c.SQLITE_OK) {
return errors.from(ret);
}
return data.len;
}
};