diff options
author | Robby Zambito <contact@robbyzambito.me> | 2025-04-23 07:26:39 -0400 |
---|---|---|
committer | Robby Zambito <contact@robbyzambito.me> | 2025-04-23 07:26:41 -0400 |
commit | 89bfbe485454ee87712364fab05024cec305aad4 (patch) | |
tree | d8c063d2e6c697108ede31a64199bc14151aa8ce | |
parent | fe26cb002db4b7bd9a53265690aba19a54ebe50f (diff) |
successfully build c interface
-rw-r--r-- | build.zig | 4 | ||||
-rw-r--r-- | include/zaprus.h | 38 | ||||
-rw-r--r-- | src/c_api.zig | 65 |
3 files changed, 85 insertions, 22 deletions
@@ -43,6 +43,8 @@ pub fn build(b: *std.Build) void { .name = "zaprus", .root_module = lib_mod, }); + static_lib.addIncludePath(.{ .cwd_relative = "include" }); + static_lib.linkLibC(); b.installArtifact(static_lib); @@ -51,6 +53,8 @@ pub fn build(b: *std.Build) void { .name = "zaprus", .root_module = lib_mod, }); + dynamic_lib.addIncludePath(.{ .cwd_relative = "include" }); + dynamic_lib.linkLibC(); b.installArtifact(dynamic_lib); diff --git a/include/zaprus.h b/include/zaprus.h index 31fe97c..b442753 100644 --- a/include/zaprus.h +++ b/include/zaprus.h @@ -1,24 +1,50 @@ // client +#include<stdint.h> +#include<stdlib.h> + int zaprus_init(void); int zaprus_deinit(void); -int zaprus_send_relay(const char* payload, usize len, char[4] dest); +int zaprus_send_relay(const char* payload, size_t len, char dest[4]); -int zaprus_send_initial_connection(const char* payload, usize len, uint16_t initial_port); +int zaprus_send_initial_connection(const char* payload, size_t len, uint16_t initial_port); -struct SaprusMessage* zaprus_connect(const char* payload, usize len); +struct SaprusMessage* zaprus_connect(const char* payload, size_t len); // message +#define SAPRUS_RELAY_MESSAGE_TYPE 0x003C +#define SAPRUS_FILE_TRANSFER_MESSAGE_TYPE 0x8888 +#define SAPRUS_CONNECTION_MESSAGE_TYPE 0x00E9 + struct SaprusMessage { - + uint16_t packet_type; + union { + struct { + struct { + char dest[4]; + }; + char *payload; + } relay; + struct { + struct { + uint16_t src_port; + uint16_t dest_port; + uint32_t seq_num; + uint32_t msg_id; + char _reserved; + char options; + }; + char *payload; + } connection; + }; }; // ptr should be freed by the caller. -int zaprus_message_to_bytes(struct SaprusMessage msg, char** ptr, usize* len); +int zaprus_message_to_bytes(struct SaprusMessage msg, char** ptr, size_t* len); // Return value should be destroyed with zaprus_message_deinit. -struct SaprusMessage* zaprus_message_from_bytes(const char* bytes, usize len); +struct SaprusMessage* zaprus_message_from_bytes(const char* bytes, size_t len); void zaprus_message_deinit(struct SaprusMessage* msg); diff --git a/src/c_api.zig b/src/c_api.zig index bb233e0..481dc78 100644 --- a/src/c_api.zig +++ b/src/c_api.zig @@ -1,5 +1,28 @@ -// client +const c = @cImport({ + @cInclude("zaprus.h"); +}); + +fn zigToCMessage(msg: ?*zaprus.Message) ?*c.SaprusMessage { + if (msg) |m| { + return switch (m.*) { + .relay => |_| @constCast(&c.SaprusMessage{}), + .connection => |_| @constCast(&c.SaprusMessage{}), + else => |_| null, + }; + } else return null; +} +fn cToZigMessage(msg: ?*c.SaprusMessage) ?*zaprus.Message { + _ = msg; + return @constCast(&zaprus.Message{ + .relay = .{ + .header = .{ .dest = @splat(0) }, + .payload = &.{0}, + }, + }); +} + +// client export fn zaprus_init() c_int { SaprusClient.init() catch return 1; return 0; @@ -10,44 +33,54 @@ export fn zaprus_deinit() c_int { return 0; } -export fn zaprus_send_relay(payload: [*]const u8, len: usize, dest: [4]u8) c_int { - SaprusClient.sendRelay(payload[0..len], dest, allocator) catch return 1; +export fn zaprus_send_relay(payload: [*]const u8, len: usize, dest: [*]u8) c_int { + SaprusClient.sendRelay(payload[0..len], dest[0..4].*, allocator) catch return 1; return 0; } export fn zaprus_send_initial_connection(payload: [*]const u8, len: usize, initial_port: u16) c_int { - SaprusClient.sendInitialConnection(payload[0..len], initial_port, allocator) catch return 1; + _ = SaprusClient.sendInitialConnection(payload[0..len], initial_port, allocator) catch return 1; return 0; } -export fn zaprus_connect(payload: [*]const u8, len: usize) ?*SaprusMessage { - return SaprusClient.connect(payload[0..len], allocator) catch null; +export fn zaprus_connect(payload: [*]const u8, len: usize) ?*c.SaprusMessage { + if (SaprusClient.connect(payload[0..len], allocator)) |msg| { + return zigToCMessage(@constCast(&(msg.?))); + } else |_| { + return null; + } } // message /// ptr should be freed by the caller. -export fn zaprus_message_to_bytes(msg: SaprusMessage, ptr: *[*]u8, len: *usize) c_int { - const bytes = msg.toBytes(allocator) catch return 1; - ptr.* = bytes[0..].*; - len.* = bytes.len; - return 0; +export fn zaprus_message_to_bytes(msg: c.SaprusMessage, ptr: *[*]u8, len: *usize) c_int { + if (cToZigMessage(@constCast(&msg))) |m| { + const bytes = m.toBytes(allocator) catch return 1; + ptr.* = bytes.ptr; + len.* = bytes.len; + return 0; + } else return 1; } /// Return value should be destroyed with zaprus_message_deinit. -export fn zaprus_message_from_bytes(bytes: [*]const u8, len: usize) ?*SaprusMessage { - return SaprusMessage.fromBytes(bytes[0..len], allocator) catch null; +export fn zaprus_message_from_bytes(bytes: [*]const u8, len: usize) ?*c.SaprusMessage { + if (zaprus.Message.fromBytes(bytes[0..len], allocator)) |msg| { + return zigToCMessage(@constCast(&msg)); + } else |_| return null; } -export fn zaprus_message_deinit(msg: *SaprusMessage) void { - msg.deinit(allocator); +export fn zaprus_message_deinit(msg: *c.SaprusMessage) void { + // noop + _ = msg; + // msg.*.deinit(allocator); } const std = @import("std"); const zaprus = @import("./root.zig"); const SaprusClient = zaprus.Client; -const SaprusMessage = zaprus.Message; +// const SaprusMessage = zaprus.Message; const allocator = std.heap.c_allocator; |