added uinteger tag to Object

This commit is contained in:
Moritz Gmeiner 2025-03-31 02:22:53 +02:00
commit 113f49f6a4
5 changed files with 66 additions and 40 deletions

View file

@ -65,7 +65,7 @@ fn deserialise_uint(bytes: []const u8) DeserialiseError!ObjectLen {
return error.BadLength; return error.BadLength;
} }
const obj = Object{ .integer = @as(i64, payload[0]) }; const obj = Object{ .uinteger = payload[0] };
return .{ .bytes_read = 2, .obj = obj }; return .{ .bytes_read = 2, .obj = obj };
}, },
@ -75,7 +75,7 @@ fn deserialise_uint(bytes: []const u8) DeserialiseError!ObjectLen {
return error.BadLength; return error.BadLength;
} }
const obj = Object{ .integer = std.mem.readInt(u16, payload[0..2], .big) }; const obj = Object{ .uinteger = std.mem.readInt(u16, payload[0..2], .big) };
return .{ .bytes_read = 3, .obj = obj }; return .{ .bytes_read = 3, .obj = obj };
}, },
@ -85,7 +85,7 @@ fn deserialise_uint(bytes: []const u8) DeserialiseError!ObjectLen {
return error.BadLength; return error.BadLength;
} }
const obj = Object{ .integer = std.mem.readInt(u32, payload[0..4], .big) }; const obj = Object{ .uinteger = std.mem.readInt(u32, payload[0..4], .big) };
return .{ .bytes_read = 5, .obj = obj }; return .{ .bytes_read = 5, .obj = obj };
}, },
@ -95,13 +95,7 @@ fn deserialise_uint(bytes: []const u8) DeserialiseError!ObjectLen {
return error.BadLength; return error.BadLength;
} }
const i = std.mem.readInt(u64, payload[0..8], .big); const obj = Object{ .uinteger = std.mem.readInt(u64, payload[0..8], .big) };
if (i > std.math.maxInt(i64)) {
return error.IntOutOfRange;
}
const obj = Object{ .integer = @intCast(i) };
return .{ .bytes_read = 9, .obj = obj }; return .{ .bytes_read = 9, .obj = obj };
}, },
@ -188,7 +182,7 @@ fn deserialise_array(alloc: std.mem.Allocator, bytes: []const u8, len: usize) De
return error.BadLength; return error.BadLength;
} }
const r = deserialise_with_count(alloc, bytes[bytes_read..]) catch |err| { const r = deserialise_with_length(alloc, bytes[bytes_read..]) catch |err| {
// on error: deinit previous objects (up to i), then return the error // on error: deinit previous objects (up to i), then return the error
for (0..i) |j| { for (0..i) |j| {
array[j].deinit(alloc); array[j].deinit(alloc);
@ -216,7 +210,7 @@ fn deserialise_map(alloc: std.mem.Allocator, bytes: []const u8, len: usize) Dese
return error.BadLength; return error.BadLength;
} }
const r1 = deserialise_with_count(alloc, bytes[bytes_read..]) catch |err| { const r1 = deserialise_with_length(alloc, bytes[bytes_read..]) catch |err| {
// on error: deinit previous objects (up to i), then return the error // on error: deinit previous objects (up to i), then return the error
for (0..i) |j| { for (0..i) |j| {
array[j].deinit(alloc); array[j].deinit(alloc);
@ -229,7 +223,7 @@ fn deserialise_map(alloc: std.mem.Allocator, bytes: []const u8, len: usize) Dese
entry.*.key = r1.obj; entry.*.key = r1.obj;
const r2 = deserialise_with_count(alloc, bytes[bytes_read..]) catch |err| { const r2 = deserialise_with_length(alloc, bytes[bytes_read..]) catch |err| {
// on error: deinit previous objects (up to i) and current key, then return the error // on error: deinit previous objects (up to i) and current key, then return the error
for (0..i) |j| { for (0..i) |j| {
array[j].deinit(alloc); array[j].deinit(alloc);
@ -256,7 +250,7 @@ fn deserialise_ext(alloc: std.mem.Allocator, type_: u8, data: []const u8, len: u
return .{ .extension = .{ .type = type_, .bytes = bytes } }; return .{ .extension = .{ .type = type_, .bytes = bytes } };
} }
pub fn deserialise_with_count(alloc: std.mem.Allocator, bytes: []const u8) DeserialiseError!ObjectLen { pub fn deserialise_with_length(alloc: std.mem.Allocator, bytes: []const u8) DeserialiseError!ObjectLen {
if (bytes.len == 0) { if (bytes.len == 0) {
return error.BadLength; return error.BadLength;
} }
@ -265,7 +259,7 @@ pub fn deserialise_with_count(alloc: std.mem.Allocator, bytes: []const u8) Deser
if (tag >> 7 == 0) { if (tag >> 7 == 0) {
// positive fixint // positive fixint
return .{ .bytes_read = 1, .obj = .{ .integer = @as(i64, tag) } }; return .{ .bytes_read = 1, .obj = .{ .uinteger = @as(u64, tag) } };
} }
if (tag >> 5 == 0b111) { if (tag >> 5 == 0b111) {
@ -552,29 +546,9 @@ pub fn deserialise_with_count(alloc: std.mem.Allocator, bytes: []const u8) Deser
} }
pub fn deserialise(alloc: std.mem.Allocator, bytes: []const u8) DeserialiseError!Object { pub fn deserialise(alloc: std.mem.Allocator, bytes: []const u8) DeserialiseError!Object {
const r = try deserialise_with_count(alloc, bytes); const r = try deserialise_with_length(alloc, bytes);
std.debug.assert(r.bytes_read == bytes.len); std.debug.assert(r.bytes_read == bytes.len);
return r.obj; return r.obj;
} }
test "pos fixint" {
const alloc = std.testing.allocator;
const bytes = [1]u8{0x07};
const obj = try deserialise(alloc, &bytes);
try std.testing.expectEqual(Object{ .integer = 0x07 }, obj);
}
test "neg fixint" {
const alloc = std.testing.allocator;
const bytes = [1]u8{0b111_11111};
const obj = try deserialise(alloc, &bytes);
try std.testing.expectEqual(Object{ .integer = -1 }, obj);
}

View file

@ -28,6 +28,7 @@ pub const Object = union(enum) {
nil, nil,
bool: bool, bool: bool,
integer: i64, integer: i64,
uinteger: u64,
float: f64, float: f64,
raw: Raw, raw: Raw,
array: []Object, array: []Object,

View file

@ -13,26 +13,30 @@ fn test_int(bytes: []const u8, expected: i64) !void {
try std.testing.expectEqual(expected, obj.integer); try std.testing.expectEqual(expected, obj.integer);
} }
test "neg fixint" {
try test_int(&[_]u8{0xFF}, -1);
}
test "int i8" { test "int i8" {
try test_int(&[_]u8{ 0xd0, 0x80 }, std.math.minInt(i8)); try test_int(&[_]u8{ 0xd0, 0x80 }, std.math.minInt(i8));
try test_int(&[_]u8{0x7f}, std.math.maxInt(i8)); try test_int(&[_]u8{ 0xd0, 0x7F }, std.math.maxInt(i8));
} }
test "int i16" { test "int i16" {
try test_int(&[_]u8{ 0xd1, 0x80, 0x00 }, std.math.minInt(i16)); try test_int(&[_]u8{ 0xd1, 0x80, 0x00 }, std.math.minInt(i16));
try test_int(&[_]u8{ 0xcd, 0x7f, 0xff }, std.math.maxInt(i16)); try test_int(&[_]u8{ 0xd1, 0x7f, 0xff }, std.math.maxInt(i16));
} }
test "int i32" { test "int i32" {
try test_int(&[_]u8{ 0xd2, 0x80, 0x00, 0x00, 0x00 }, std.math.minInt(i32)); try test_int(&[_]u8{ 0xd2, 0x80, 0x00, 0x00, 0x00 }, std.math.minInt(i32));
try test_int(&[_]u8{ 0xce, 0x7f, 0xff, 0xff, 0xff }, std.math.maxInt(i32)); try test_int(&[_]u8{ 0xd2, 0x7f, 0xff, 0xff, 0xff }, std.math.maxInt(i32));
} }
test "int i64" { test "int i64" {
try test_int(&[_]u8{ 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, std.math.minInt(i64)); try test_int(&[_]u8{ 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, std.math.minInt(i64));
try test_int(&[_]u8{ 0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, std.math.maxInt(i64)); try test_int(&[_]u8{ 0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, std.math.maxInt(i64));
} }

View file

@ -3,6 +3,7 @@ const std = @import("std");
pub const binary = @import("binary.zig"); pub const binary = @import("binary.zig");
pub const string = @import("string.zig"); pub const string = @import("string.zig");
pub const int = @import("int.zig"); pub const int = @import("int.zig");
pub const uint = @import("uint.zig");
pub const msgpack = @import("msgpack"); pub const msgpack = @import("msgpack");

View file

@ -0,0 +1,46 @@
const std = @import("std");
pub const msgpack = @import("msgpack");
const deserialise = msgpack.deserialise.deserialise;
fn test_uint(bytes: []const u8, expected: u64) !void {
const alloc = std.testing.allocator;
const obj = try deserialise(alloc, bytes);
defer obj.deinit(alloc);
try std.testing.expectEqual(expected, obj.uinteger);
}
test "pos fixint" {
try test_uint(&[_]u8{0x00}, std.math.minInt(u8));
try test_uint(&[_]u8{0x07}, 0x07);
try test_uint(&[_]u8{0x7F}, 0x7F);
}
test "int u8" {
try test_uint(&[_]u8{ 0xcc, 0x00 }, std.math.minInt(u8));
try test_uint(&[_]u8{ 0xcc, 0xff }, std.math.maxInt(u8));
}
test "int u16" {
try test_uint(&[_]u8{ 0xcd, 0x00, 0x00 }, std.math.minInt(u16));
try test_uint(&[_]u8{ 0xcd, 0xff, 0xff }, std.math.maxInt(u16));
}
test "int u32" {
try test_uint(&[_]u8{ 0xce, 0x00, 0x00, 0x00, 0x00 }, std.math.minInt(u32));
try test_uint(&[_]u8{ 0xce, 0xff, 0xff, 0xff, 0xff }, std.math.maxInt(u32));
}
test "int u64" {
try test_uint(&[_]u8{ 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, std.math.minInt(u64));
try test_uint(&[_]u8{ 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, std.math.maxInt(u64));
}