diff options
| author | 2021-04-22 21:08:16 +0200 | |
|---|---|---|
| committer | 2021-04-22 21:08:16 +0200 | |
| commit | 84062cd07526f68763f0ad5fbc0290ef683c5c37 (patch) | |
| tree | ee4e7a6725dd74ca9206452d07b6f8b95074cda5 | |
| parent | Merge pull request #26 from daurnimator/return-error (diff) | |
| parent | Allow reading into static size arrays as long as size matches (diff) | |
| download | zig-sqlite-84062cd07526f68763f0ad5fbc0290ef683c5c37.tar.gz zig-sqlite-84062cd07526f68763f0ad5fbc0290ef683c5c37.tar.xz zig-sqlite-84062cd07526f68763f0ad5fbc0290ef683c5c37.zip | |
Merge pull request #28 from daurnimator/array-exact-size
Allow reading into static size arrays as long as size matches
Diffstat (limited to '')
| -rw-r--r-- | sqlite.zig | 23 |
1 files changed, 12 insertions, 11 deletions
| @@ -630,32 +630,33 @@ pub fn Iterator(comptime Type: type) type { | |||
| 630 | 630 | ||
| 631 | // readArray reads a sqlite BLOB or TEXT column into an array of u8. | 631 | // readArray reads a sqlite BLOB or TEXT column into an array of u8. |
| 632 | // | 632 | // |
| 633 | // We also require the array to have a sentinel because otherwise we have no way | 633 | // We also require the array to be the exact size of the data, or have a sentinel; |
| 634 | // of communicating the end of the data to the caller. | 634 | // otherwise we have no way of communicating the end of the data to the caller. |
| 635 | // | 635 | // |
| 636 | // If the array is too small for the data an error will be returned. | 636 | // If the array is too small for the data an error will be returned. |
| 637 | fn readArray(self: *Self, comptime ArrayType: type, _i: usize) error{ArrayTooSmall}!ArrayType { | 637 | fn readArray(self: *Self, comptime ArrayType: type, _i: usize) !ArrayType { |
| 638 | const i = @intCast(c_int, _i); | 638 | const i = @intCast(c_int, _i); |
| 639 | const type_info = @typeInfo(ArrayType); | 639 | const type_info = @typeInfo(ArrayType); |
| 640 | 640 | ||
| 641 | var ret: ArrayType = undefined; | 641 | var ret: ArrayType = undefined; |
| 642 | switch (type_info) { | 642 | switch (type_info) { |
| 643 | .Array => |arr| { | 643 | .Array => |arr| { |
| 644 | comptime if (arr.sentinel == null) { | ||
| 645 | @compileError("cannot populate array of " ++ @typeName(arr.child) ++ ", arrays must have a sentinel"); | ||
| 646 | }; | ||
| 647 | |||
| 648 | switch (arr.child) { | 644 | switch (arr.child) { |
| 649 | u8 => { | 645 | u8 => { |
| 650 | const data = c.sqlite3_column_blob(self.stmt, i); | ||
| 651 | const size = @intCast(usize, c.sqlite3_column_bytes(self.stmt, i)); | 646 | const size = @intCast(usize, c.sqlite3_column_bytes(self.stmt, i)); |
| 647 | if (arr.sentinel == null) { | ||
| 648 | if (size != arr.len) return error.ArraySizeMisMatch; | ||
| 649 | } else if (size >= @as(usize, arr.len)) { | ||
| 650 | return error.ArrayTooSmall; | ||
| 651 | } | ||
| 652 | 652 | ||
| 653 | if (size >= @as(usize, arr.len)) return error.ArrayTooSmall; | 653 | const data = c.sqlite3_column_blob(self.stmt, i); |
| 654 | |||
| 655 | const ptr = @ptrCast([*c]const u8, data)[0..size]; | 654 | const ptr = @ptrCast([*c]const u8, data)[0..size]; |
| 656 | 655 | ||
| 657 | mem.copy(u8, ret[0..], ptr); | 656 | mem.copy(u8, ret[0..], ptr); |
| 658 | ret[size] = arr.sentinel.?; | 657 | if (arr.sentinel) |s| { |
| 658 | ret[size] = s; | ||
| 659 | } | ||
| 659 | }, | 660 | }, |
| 660 | else => @compileError("cannot populate field " ++ field.name ++ " of type array of " ++ @typeName(arr.child)), | 661 | else => @compileError("cannot populate field " ++ field.name ++ " of type array of " ++ @typeName(arr.child)), |
| 661 | } | 662 | } |