WIP: varint-extension
[?]
Jun 13, 2023, 2:57 AM
H3JTOAUEPPD7BWQA3M6WTYXPTGPEJXZLNIDPRJ7MJKZWEYNRZOTACDependencies
Change contents
- file addition: varint-extension[2.5]
- file addition: varint-extension.zig[0.6]
// https://csprimer.com/watch/varint-extension/// inspired by https://github.com/adamserafini/zaml/blob/27b2d54ffb39aace5d5d58f0aa75396c3e6fe84d/zamlmodule.zigconst std = @import("std");const varint = @import("protobuf-varint");const py = @cImport({@cDefine("PY_SSIZE_T_CLEAN", {});@cInclude("Python.h");});fn cvarint_encode(self: [*c]py.PyObject,args: [*c]py.PyObject,) callconv(.C) [*]py.PyObject {_ = self;var cvalue_K: CUInt = undefined;if (!py.PyArg_ParseTuple(args, "K", &cvalue_K)) return null;if (!canIntCast(u64, cvalue_K)) return null;const value = @intCast(u64, cvalue_K);var buffer: [10]varint.VarintByte = undefined;const result_vbytes = varint.encode(value, &buffer);// see https://docs.python.org/3/c-api/arg.html#building-valuesreturn py.Py_BuildValue("y#",@ptrCast([*c]u8, result_vbytes.ptr),@as(py.Py_ssize_t, result_vbytes.len),);}fn cvarint_decode(self: [*c]py.PyObject,args: [*c]py.PyObject,) callconv(.C) [*]py.PyObject {_ = self;var cvalue_ptr: [*c]u8 = undefined;var cvalue_len: py.Py_ssize_t = undefined;if (!py.PyArg_ParseTuple(args, "K", &cvalue_ptr, &cvalue_len)) return null;if (!cvalue_ptr) return null;const value = @ptrCast([]const varint.VarintByte, cvalue_ptr[0..cvalue_len]);const result = varint.decode(value) orelse return null;return py.Py_BuildValue("K", @as(CUInt, result));}/// A c-native uint at least as big as u64.const CUInt: type = c_ulonglong;comptime {std.debug.assert(@bitSizeOf(CUInt) >= @bitSizeOf(u64));}/// Runtime check that an int value fits in another int type.fn canIntCast(comptime T: type, value: anytype) bool {return @truncate(@TypeOf(value), @truncate(T, value)) != value;}var CVarintMethods = [_]py.PyMethodDef{py.PyMethodDef{.ml_name = "encode",.ml_meth = cvarint_encode,.ml_flags = py.METH_VARARGS,.ml_doc = "Encode an integer as varint.",},py.PyMethodDef{.ml_name = "decode",.ml_meth = cvarint_decode,.ml_flags = py.METH_VARARGS,.ml_doc = "Decode varint bytes to an integer.",},py.PyMethodDef{.ml_name = null,.ml_meth = null,.ml_flags = 0,.ml_doc = null,},};var cvarintmodule = py.PyModuleDef{.m_base = py.PyModuleDef_Base{.ob_base = py.PyObject{.ob_refcnt = 1,.ob_type = null,},.m_init = null,.m_index = 0,.m_copy = null,},.m_name = "cvarint",.m_doc = "A C implementation of protobuf varint encoding",.m_size = -1,.m_methods = &CVarintMethods,.m_slots = null,.m_traverse = null,.m_clear = null,.m_free = null,};pub export fn PyInit_cvarint() [*]py.PyObject {return py.PyModule_Create(&cvarintmodule);} - file addition: build.zig[0.6]
const std = @import("std");// Although this function looks imperative, note that its job is to// declaratively construct a build graph that will be executed by an external// runner.pub fn build(b: *std.Build) void {// Standard target options allows the person running `zig build` to choose// what target to build for. Here we do not override the defaults, which// means any target is allowed, and the default is native. Other options// for restricting supported target set are available.const target = b.standardTargetOptions(.{});// Standard optimization options allow the person running `zig build` to select// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not// set a preferred release mode, allowing the user to decide how to optimize.const optimize = b.standardOptimizeOption(.{});const lib = b.addSharedLibrary(.{.name = "varint-extension",// In this case the main source file is merely a path, however, in more// complicated build scripts, this could be a generated file..root_source_file = .{ .path = "varint-extension.zig" },.target = target,.optimize = optimize,});// Add protobuf varint Zig implementation as a dependency.const protobuf_varint = b.addModule("protobuf-varint", .{ .source_file = .{ .path = "../../bits-and-bytes/protobuf-varint.zig" } });lib.addModule("protobuf-varint", protobuf_varint);// This declares intent for the library to be installed into the standard// location when the user invokes the "install" step (the default step when// running `zig build`).b.installArtifact(lib);// Creates a step for unit testing. This only builds the test executable// but does not run it.const main_tests = b.addTest(.{.root_source_file = .{ .path = "src/main.zig" },.target = target,.optimize = optimize,});const run_main_tests = b.addRunArtifact(main_tests);// This creates a build step. It will be visible in the `zig build --help` menu,// and can be selected like this: `zig build test`// This will evaluate the `test` step rather than the default, which is "install".const test_step = b.step("test", "Run library tests");test_step.dependOn(&run_main_tests.step);} - replacement in zig/src/computer-systems/bits-and-bytes/protobuf-varint.zig at line 70
pub fn decode(buffer: []const VarintByte) !u64 {pub fn decode(buffer: []const VarintByte) DecodeError!u64 { - edit in zig/.gitignore at line 2[5.875]
zig-out