diff --git a/src/qtshit/rangeiter.zig b/src/qtshit/rangeiter.zig new file mode 100644 index 0000000..2867355 --- /dev/null +++ b/src/qtshit/rangeiter.zig @@ -0,0 +1,17 @@ +pub fn range(comptime T: type, begin: T, end: T) Range(T) { + return Range(T){ .curr = begin, .end = end }; +} + +fn Range(comptime T: type) type { + return struct { + curr: T, + end: T, + + pub fn next(self: *Range(T)) ?T { + if (self.curr >= self.end) return null; + const n = self.curr; + self.curr += 1; + return n; + } + }; +} diff --git a/src/qtshit/read.zig b/src/qtshit/read.zig index 919a77a..e5dee80 100644 --- a/src/qtshit/read.zig +++ b/src/qtshit/read.zig @@ -1,5 +1,6 @@ const std = @import("std"); const qvar = @import("./qvariant.zig"); +const range = @import("./rangeiter.zig").range; pub fn get_int(reader: anytype) !u32 { return try reader.readIntBig(u32); @@ -60,13 +61,7 @@ pub fn get_stringlist(reader: anytype, allocator: *std.mem.Allocator) !std.Array return strList; } -pub fn get_qvariant(reader: anytype) !u32 { - var type_id = try get_int(reader); - // TODO: make nop variants work??? - return type_id; -} - -pub fn get_variant_t(reader: anytype, type_id: u32, allocator: *std.mem.Allocator) !qvar.QVariant { +pub fn get_variant_t(reader: anytype, type_id: u32, allocator: *std.mem.Allocator) (@TypeOf(reader).Error || error{EndOfStream} || error{OutOfMemory})!qvar.QVariant { switch (type_id) { @enumToInt(qvar.QVariantTypes.byte) => { var byte = try get_byte(reader); @@ -76,6 +71,10 @@ pub fn get_variant_t(reader: anytype, type_id: u32, allocator: *std.mem.Allocato var int = try get_int(reader); return qvar.QVariant{ .int = int }; }, + @enumToInt(qvar.QVariantTypes.qmap) => { + var map = try get_qvariantmap(reader, allocator); + return qvar.QVariant{ .qmap = map }; + }, @enumToInt(qvar.QVariantTypes.string) => { var str = try get_string(reader, allocator); return qvar.QVariant{ .string = str }; @@ -98,7 +97,21 @@ pub fn get_variant_t(reader: anytype, type_id: u32, allocator: *std.mem.Allocato } pub fn get_variant(reader: anytype, allocator: *std.mem.Allocator) !qvar.QVariant { - var type_id = try get_qvariant(reader); + var type_id = try get_int(reader); _ = try get_byte(reader); return try get_variant_t(reader, type_id, allocator); } + +pub fn get_qvariantmap(reader: anytype, allocator: *std.mem.Allocator) !std.StringHashMap(qvar.QVariant) { + var map = std.StringHashMap(qvar.QVariant).init(allocator); + var numItems = try get_int(reader); + + var iter = range(u32, 0, numItems); + while (iter.next()) |i| { + var key = try get_string(reader, allocator); + var value = try get_variant(reader, allocator); + try map.put(key, value); + } + + return map; +} diff --git a/src/qtshit/test.zig b/src/qtshit/test.zig index 1472611..1714ab3 100644 --- a/src/qtshit/test.zig +++ b/src/qtshit/test.zig @@ -129,3 +129,26 @@ test "read/write int variant" { try expect(val.int == 1312); } + + + +test "read/write qvariantmap" { + var byteList = std.ArrayList(u8).init(global_allocator); + defer byteList.deinit(); + + var map = std.StringHashMap(qvar.QVariant).init(global_allocator); + defer map.deinit(); + try map.put("testkey", .{ .int = 1337 }); + try write.add_qvariantmap(byteList.writer(), global_allocator, map); + + var fBS = std.io.fixedBufferStream(byteList.items); + var val = try read.get_variant(fBS.reader(), global_allocator); + var qmap = val.qmap; + + var testKey = qmap.get("testkey"); + if (testKey) |key| { + try expect(key.int == 1337); + } else { + try expect(!true); + } +} diff --git a/src/qtshit/write.zig b/src/qtshit/write.zig index 71fd3da..f267975 100644 --- a/src/qtshit/write.zig +++ b/src/qtshit/write.zig @@ -74,6 +74,7 @@ pub fn add_qvariant(writer: anytype, allocator: *std.mem.Allocator, variant: qva pub fn add_qvariantmap(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(qvar.QVariant)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void { var data = std.ArrayList(u8).init(allocator); + defer data.deinit(); var writeIterator = map.iterator(); while (writeIterator.next()) |entry| { try add_string(data.writer(), allocator, entry.key); @@ -81,11 +82,9 @@ pub fn add_qvariantmap(writer: anytype, allocator: *std.mem.Allocator, map: std. } // qvariantmap type - try add_int(writer, 8); // 4 - // unknown value - try add_byte(writer, 0); // 1 - // elements - try add_int(writer, map.count()); // 4 + try add_int(writer, @enumToInt(qvar.QVariantTypes.qmap)); + try add_byte(writer, 0); + try add_int(writer, map.count()); try writer.writeAll(data.items); return;