mgtzm/src/Db.zig

81 lines
1.9 KiB
Zig

const c = @cImport({
@cInclude("tkrzw_langc.h");
});
const Self = @This();
const std = @import("std");
pub const free = c.free;
dbm: *c.TkrzwDBM,
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const encode_len = 4;
pub fn numEncode(num: usize) ![encode_len]u8 {
return uintEncode(num, 4, chars);
}
pub fn numDecode(str: []const u8) usize {
return uintDecode(str, chars);
}
const EncodeError = error{
NumberTooBig,
};
fn uintEncode(num: usize, comptime bufflen: usize, comptime charset: []const u8) ![bufflen]u8 {
// Check if the number is bigger than the maximum possible number
var pow = comptime std.math.pow(usize, charset.len, bufflen);
if (num >= pow) return EncodeError.NumberTooBig;
var buff = [_]u8{charset[0]} ** bufflen;
var num_i: usize = num;
for (buff) |*pos| {
pow /= charset.len;
pos.* = charset[@divTrunc(num_i, pow)];
num_i %= pow;
}
return buff;
}
fn uintDecode(str: []const u8, comptime charset: []const u8) usize {
var ret: usize = 0;
for (str) |needle, i| {
for (charset) |blade, j| {
if (needle == blade) {
ret += std.math.pow(usize, charset.len, str.len - i - 1) * j;
break;
}
}
}
return ret;
}
pub fn open(path: [:0]const u8, writable: bool, params: [:0]const u8) Self {
return Self{
.dbm = c.tkrzw_dbm_open(path, writable, params),
};
}
pub fn set(self: *Self, key: []const u8, value: []const u8) void {
const key_len = @intCast(i32, key.len);
const value_len = @intCast(i32, value.len);
_ = c.tkrzw_dbm_set(self.dbm, key.ptr, key_len, value.ptr, value_len, true);
}
pub fn get(self: *Self, key: []const u8) []u8 {
const key_len = @intCast(i32, key.len);
var len: i32 = 0;
var ret = c.tkrzw_dbm_get(self.dbm, key.ptr, key_len, &len);
return ret[0..@intCast(usize, len)];
}