From dada29e25a52db359a03102c0cdab0950e6448b9 Mon Sep 17 00:00:00 2001 From: Kitteh Date: Wed, 2 Jun 2021 21:31:27 +0100 Subject: [PATCH] Move read code into seporate iles. --- src/client.zig | 14 +- src/main.zig | 5 +- src/qtshit/qvariant.zig | 156 ----------------- src/qtshit/read.zig | 163 ++---------------- src/qtshit/read/readByte.zig | 3 + src/qtshit/read/readInt.zig | 3 + src/qtshit/read/readQByteArray.zig | 18 ++ src/qtshit/read/readQStringList.zig | 17 ++ src/qtshit/read/readQVariant.zig | 12 ++ src/qtshit/read/readQVariantList.zig | 20 +++ src/qtshit/read/readQVariantMap.zig | 23 +++ src/qtshit/read/readQVariantT.zig | 67 +++++++ src/qtshit/read/readShort.zig | 3 + src/qtshit/read/readSignedByte.zig | 3 + src/qtshit/read/readString.zig | 27 +++ src/qtshit/read/readUInt.zig | 3 + src/qtshit/test.zig | 4 +- src/qtshit/types/QVariant.zig | 16 ++ src/qtshit/types/QVariantTypes.zig | 12 ++ src/qtshit/types/UserTypes.zig | 3 + src/qtshit/utils/QVariantTypeID.zig | 37 ++++ .../{rangeiter.zig => utils/RangeIter.zig} | 0 src/qtshit/utils/freeQVariant.zig | 43 +++++ src/qtshit/utils/prettyPrintQVariant.zig | 64 +++++++ src/qtshit/write.zig | 16 +- 25 files changed, 409 insertions(+), 323 deletions(-) delete mode 100644 src/qtshit/qvariant.zig create mode 100644 src/qtshit/read/readByte.zig create mode 100644 src/qtshit/read/readInt.zig create mode 100644 src/qtshit/read/readQByteArray.zig create mode 100644 src/qtshit/read/readQStringList.zig create mode 100644 src/qtshit/read/readQVariant.zig create mode 100644 src/qtshit/read/readQVariantList.zig create mode 100644 src/qtshit/read/readQVariantMap.zig create mode 100644 src/qtshit/read/readQVariantT.zig create mode 100644 src/qtshit/read/readShort.zig create mode 100644 src/qtshit/read/readSignedByte.zig create mode 100644 src/qtshit/read/readString.zig create mode 100644 src/qtshit/read/readUInt.zig create mode 100644 src/qtshit/types/QVariant.zig create mode 100644 src/qtshit/types/QVariantTypes.zig create mode 100644 src/qtshit/types/UserTypes.zig create mode 100644 src/qtshit/utils/QVariantTypeID.zig rename src/qtshit/{rangeiter.zig => utils/RangeIter.zig} (100%) create mode 100644 src/qtshit/utils/freeQVariant.zig create mode 100644 src/qtshit/utils/prettyPrintQVariant.zig diff --git a/src/client.zig b/src/client.zig index ac00140..218bce3 100644 --- a/src/client.zig +++ b/src/client.zig @@ -1,7 +1,9 @@ const std = @import("std"); const read = @import("./qtshit/read.zig"); const write = @import("./qtshit/write.zig"); -const qvar = @import("./qtshit/qvariant.zig"); +const QVariantType = @import("./qtshit/types/QVariant.zig").QVariant; +const prettyPrintQVariant = @import("./qtshit/utils/prettyPrintQVariant.zig").prettyPrintQVariant; +const freeQVariant = @import("./qtshit/utils/freeQVariant.zig").freeQVariant; fn dumpDebug(name: []const u8, list: std.ArrayList(u8)) !void { std.debug.print("dumpDebug list len {d}\n", .{list.items.len}); @@ -33,7 +35,7 @@ pub const Client = struct { pub fn quassel_init_packet(s: *Client) !void { var list = std.ArrayList(u8).init(s.allocator); - var map = std.StringHashMap(qvar.QVariant).init(s.allocator); + var map = std.StringHashMap(QVariantType).init(s.allocator); try map.put("MsgType", .{ .String = "ClientInit" }); try map.put("ProtocolVersion", .{ .UInt = 10 }); @@ -49,7 +51,7 @@ pub const Client = struct { std.debug.print("\n\nInitPacket: \n", .{}); - qvar.pretty_print_variant(.{.QVariantMap = map}, 0); + prettyPrintQVariant(.{ .QVariantMap = map }, 0); try s.read_quassel_packet(); } @@ -57,7 +59,7 @@ pub const Client = struct { pub fn quassel_login(s: *Client, username: []const u8, password: []const u8) !void { var list = std.ArrayList(u8).init(s.allocator); - var map = std.StringHashMap(qvar.QVariant).init(s.allocator); + var map = std.StringHashMap(QVariantType).init(s.allocator); try map.put("MsgType", .{ .String = "ClientLogin" }); try map.put("User", .{ .String = username }); @@ -73,8 +75,8 @@ pub const Client = struct { var size = read.readUInt(s.stream.reader()); std.debug.print("\n\nQuassel Packet: \n", .{}); var varient = try read.readQVariant(s.stream.reader(), s.allocator); - qvar.pretty_print_variant(varient, 0); - qvar.freeQVariant(varient, s.allocator); + prettyPrintQVariant(varient, 0); + freeQVariant(varient, s.allocator); } }; diff --git a/src/main.zig b/src/main.zig index 09791e5..e26b36f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -13,6 +13,7 @@ pub fn main() !void { try client.handshake(); try client.quassel_init_packet(); try client.quassel_login("z", "password"); - try client.read_quassel_packet(); - + while (true) { + try client.read_quassel_packet(); + } } diff --git a/src/qtshit/qvariant.zig b/src/qtshit/qvariant.zig deleted file mode 100644 index 74de5d2..0000000 --- a/src/qtshit/qvariant.zig +++ /dev/null @@ -1,156 +0,0 @@ -const std = @import("std"); -const range = @import("./rangeiter.zig").range; - -pub const QVariant = union(enum) { - Int: i32, - UInt: u32, - Short: u16, - Byte: u8, - String: []const u8, - QByteArray: []u8, - QStringList: [][]const u8, - QVariantList: []QVariant, - QVariantMap: std.StringHashMap(QVariant), -}; - -pub const QVariantTypes = enum(u32) { - Byte = 1, - Int = 2, - UInt = 3, - QVariantMap = 8, - QVariantList = 9, - String = 10, - QStringList = 11, - QByteArray = 12, - Short = 133, -}; - -pub fn qvariant_type_id(variant: QVariant) !u32 { - switch (variant) { - .Byte => { - return @enumToInt(QVariantTypes.Byte); - }, - .Int => { - return @enumToInt(QVariantTypes.Int); - }, - .UInt => { - return @enumToInt(QVariantTypes.UInt); - }, - .QVariantMap => { - return @enumToInt(QVariantTypes.QVariantMap); - }, - .QVariantList => { - return @enumToInt(QVariantTypes.QVariantList); - }, - .String => { - return @enumToInt(QVariantTypes.String); - }, - .QStringList => { - return @enumToInt(QVariantTypes.QStringList); - }, - .QByteArray => { - return @enumToInt(QVariantTypes.QByteArray); - }, - .Short => { - return @enumToInt(QVariantTypes.Short); - }, - } -} - -pub fn print_indent_level(indentLevel: u64) void { - var iter = range(u64, 0, indentLevel); - while (iter.next()) |i| { - std.debug.print(" ", .{}); - } -} - -pub fn pretty_print_variant(variant: QVariant, indentLevel: u64) void { - print_indent_level(indentLevel); - - switch (variant) { - .Byte => |b| { - std.debug.print("Byte: {d}\n", .{b}); - }, - .Int => |i| { - std.debug.print("Int: {d}\n", .{i}); - }, - .UInt => |i| { - std.debug.print("UInt: {d}\n", .{i}); - }, - .QVariantMap => |q| { - std.debug.print("QVariantMap:\n", .{}); - var qMapIter = q.iterator(); - while (qMapIter.next()) |v| { - print_indent_level(indentLevel + 1); - std.debug.print("Key: \"{s}\"\n", .{v.key}); - print_indent_level(indentLevel + 1); - std.debug.print("Value:\n", .{}); - pretty_print_variant(v.value, indentLevel + 2); - } - }, - .QVariantList => |l| { - std.debug.print("QVariantList:\n", .{}); - - for (l) |varient, i| { - print_indent_level(indentLevel + 1); - std.debug.print("Item #{d}\n", .{i}); - pretty_print_variant(varient, indentLevel + 2); - } - }, - .String => |s| { - std.debug.print("String: \"{s}\"\n", .{s}); - }, - .QStringList => |l| { - std.debug.print("QStringList:\n", .{}); - - for (l) |str, i| { - print_indent_level(indentLevel + 1); - std.debug.print("\"{s}\" \n", .{str}); - } - }, - .QByteArray => {}, - .Short => |s| { - std.debug.print("Short: \"{d}\"\n", .{s}); - }, - } -} - - -pub fn freeQVariant(variant: QVariant, allocator: *std.mem.Allocator) void { - switch (variant) { - .Byte, .Int, .UInt, .Short => { - // Static - }, - - .QVariantMap => |q| { - var qMapIter = q.iterator(); - while (qMapIter.next()) |v| { - allocator.free(v.key); - freeQVariant(v.value, allocator); - } - // Compiler bug maybe? doesnt want me to drop const so have to store it in a variable - var qi = q; - qi.deinit(); - }, - - .QVariantList => |l| { - for (l) |varient, i| { - freeQVariant(varient, allocator); - } - allocator.free(l); - }, - .String => |s| { - allocator.free(s); - }, - .QStringList => |l| { - for (l) |varient, i| { - allocator.free(varient); - } - allocator.free(l); - }, - .QByteArray => |ba| { - allocator.free(ba); - }, - } -} - diff --git a/src/qtshit/read.zig b/src/qtshit/read.zig index 73d2879..ee521ba 100644 --- a/src/qtshit/read.zig +++ b/src/qtshit/read.zig @@ -1,151 +1,12 @@ -const std = @import("std"); -const qvar = @import("./qvariant.zig"); -const range = @import("./rangeiter.zig").range; - -pub fn readInt(reader: anytype) !i32 { - return try reader.readIntBig(i32); -} - -pub fn readUInt(reader: anytype) !u32 { - return try reader.readIntBig(u32); -} - -pub fn readShort(reader: anytype) !u16 { - return try reader.readIntBig(u16); -} - -pub fn readByte(reader: anytype) !u8 { - return try reader.readByte(); -} - -pub fn readSignedByte(reader: anytype) !i8 { - return try reader.readIntBig(i8); -} - -pub fn readQByteArray(reader: anytype, allocator: *std.mem.Allocator) ![]u8 { - var length = try readUInt(reader); - - var byteList = try allocator.alloc(u8, @intCast(usize, length)); - - var index: usize = 0; - while (true) { - if (index == length) return byteList; - - const byte = try readByte(reader); - byteList[index] = byte; - index += 1; - } -} - -pub fn readString(reader: anytype, allocator: *std.mem.Allocator) ![]u8 { - var data = std.ArrayList(u8).init(allocator); - defer data.deinit(); - - var length = try readInt(reader); - var chars = @divTrunc(length, 2); - - var index: usize = 0; - while (true) { - if (index == chars) break; - - const byte = try readShort(reader); - try data.append(@truncate(u8, byte)); - index += 1; - } - - var ut8Str = try allocator.alloc(u8, @intCast(usize, chars)); - for (data.items) |char, i| { - ut8Str[i] = char; - } - - return ut8Str; -} - -pub fn readQVariantList(reader: anytype, allocator: *std.mem.Allocator) ![]qvar.QVariant { - var length = try readUInt(reader); - var variantList = try allocator.alloc(qvar.QVariant, @intCast(usize, length)); - - var iter = range(u32, 0, length); - while (iter.next()) |i| { - variantList[i] = try readQVariant(reader, allocator); - } - - return variantList; -} - -pub fn readQStringList(reader: anytype, allocator: *std.mem.Allocator) ![][]const u8 { - var length = try readUInt(reader); - var stringList = try allocator.alloc([]const u8, @intCast(usize, length)); - - var iter = range(u32, 0, length); - while (iter.next()) |i| { - stringList[i] = try readString(reader, allocator); - } - - return stringList; -} - -pub fn readQVariantMap(reader: anytype, allocator: *std.mem.Allocator) !std.StringHashMap(qvar.QVariant) { - var map = std.StringHashMap(qvar.QVariant).init(allocator); - var numItems = try readUInt(reader); - - var iter = range(u32, 0, numItems); - while (iter.next()) |i| { - var key = try readString(reader, allocator); - var value = try readQVariant(reader, allocator); - try map.put(key, value); - } - - return map; -} - -pub fn readQVariantT(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 readByte(reader); - return qvar.QVariant{ .Byte = byte }; - }, - @enumToInt(qvar.QVariantTypes.Int) => { - var int = try readInt(reader); - return qvar.QVariant{ .Int = int }; - }, - @enumToInt(qvar.QVariantTypes.UInt) => { - var uint = try readUInt(reader); - return qvar.QVariant{ .UInt = uint }; - }, - @enumToInt(qvar.QVariantTypes.QVariantMap) => { - var map = try readQVariantMap(reader, allocator); - return qvar.QVariant{ .QVariantMap = map }; - }, - @enumToInt(qvar.QVariantTypes.QVariantList) => { - var list = try readQVariantList(reader, allocator); - return qvar.QVariant{ .QVariantList = list }; - }, - @enumToInt(qvar.QVariantTypes.String) => { - var str = try readString(reader, allocator); - return qvar.QVariant{ .String = str }; - }, - @enumToInt(qvar.QVariantTypes.QStringList) => { - var strlist = try readQStringList(reader, allocator); - return qvar.QVariant{ .QStringList = strlist }; - }, - @enumToInt(qvar.QVariantTypes.QByteArray) => { - var bArray = try readQByteArray(reader, allocator); - return qvar.QVariant{ .QByteArray = bArray }; - }, - @enumToInt(qvar.QVariantTypes.Short) => { - var short = try readShort(reader); - return qvar.QVariant{ .Short = short }; - }, - else => { - @panic("Unknown Type"); - }, - } - return qvar.QVariant{ .empty = true }; -} - -pub fn readQVariant(reader: anytype, allocator: *std.mem.Allocator) !qvar.QVariant { - var type_id = try readUInt(reader); - _ = try readByte(reader); - return try readQVariantT(reader, type_id, allocator); -} +pub const readInt = @import("./read/readInt.zig").readInt; +pub const readUInt = @import("./read/readUInt.zig").readUInt; +pub const readShort = @import("./read/readShort.zig").readShort; +pub const readByte = @import("./read/readByte.zig").readByte; +pub const readSignedByte = @import("./read/readSignedByte.zig").readSignedByte; +pub const readQByteArray = @import("./read/readQByteArray.zig").readQByteArray; +pub const readString = @import("./read/readString.zig").readString; +pub const readQVariantList = @import("./read/readQVariantList.zig").readQVariantList; +pub const readQVariantT = @import("./read/readQVariantT.zig").readQVariantT; +pub const readQVariant = @import("./read/readQVariant.zig").readQVariant; +pub const readQVariantMap = @import("./read/readQVariantMap.zig").readQVariantMap; +pub const readQStringList = @import("./readQStringList.zig").readQStringList; diff --git a/src/qtshit/read/readByte.zig b/src/qtshit/read/readByte.zig new file mode 100644 index 0000000..2d6c998 --- /dev/null +++ b/src/qtshit/read/readByte.zig @@ -0,0 +1,3 @@ +pub fn readByte(reader: anytype) !u8 { + return try reader.readByte(); +} diff --git a/src/qtshit/read/readInt.zig b/src/qtshit/read/readInt.zig new file mode 100644 index 0000000..8ca690f --- /dev/null +++ b/src/qtshit/read/readInt.zig @@ -0,0 +1,3 @@ +pub fn readInt(reader: anytype) !i32 { + return try reader.readIntBig(i32); +} diff --git a/src/qtshit/read/readQByteArray.zig b/src/qtshit/read/readQByteArray.zig new file mode 100644 index 0000000..56f8f8b --- /dev/null +++ b/src/qtshit/read/readQByteArray.zig @@ -0,0 +1,18 @@ +const std = @import("std"); +const readUInt = @import("./readUInt.zig").readUInt; +const readByte = @import("./readByte.zig").readByte; + +pub fn readQByteArray(reader: anytype, allocator: *std.mem.Allocator) ![]u8 { + var length = try readUInt(reader); + + var byteList = try allocator.alloc(u8, @intCast(usize, length)); + + var index: usize = 0; + while (true) { + if (index == length) return byteList; + + const byte = try readByte(reader); + byteList[index] = byte; + index += 1; + } +} diff --git a/src/qtshit/read/readQStringList.zig b/src/qtshit/read/readQStringList.zig new file mode 100644 index 0000000..c6dae08 --- /dev/null +++ b/src/qtshit/read/readQStringList.zig @@ -0,0 +1,17 @@ +const std = @import("std"); +const range = @import("../utils/RangeIter.zig").range; + +const readUInt = @import("./readUInt.zig").readUInt; +const readString = @import("./readString.zig").readString; + +pub fn readQStringList(reader: anytype, allocator: *std.mem.Allocator) ![][]const u8 { + var length = try readUInt(reader); + var stringList = try allocator.alloc([]const u8, @intCast(usize, length)); + + var iter = range(u32, 0, length); + while (iter.next()) |i| { + stringList[i] = try readString(reader, allocator); + } + + return stringList; +} diff --git a/src/qtshit/read/readQVariant.zig b/src/qtshit/read/readQVariant.zig new file mode 100644 index 0000000..1124a81 --- /dev/null +++ b/src/qtshit/read/readQVariant.zig @@ -0,0 +1,12 @@ +const std = @import("std"); +const readUInt = @import("./readUInt.zig").readUInt; +const readByte = @import("./readByte.zig").readByte; +const readQVariantT = @import("./readQVariantT.zig").readQVariantT; +const QVariant = @import("../types/QVariant.zig").QVariant; + + +pub fn readQVariant(reader: anytype, allocator: *std.mem.Allocator) !QVariant { + var type_id = try readUInt(reader); + _ = try readByte(reader); + return try readQVariantT(reader, type_id, allocator); +} diff --git a/src/qtshit/read/readQVariantList.zig b/src/qtshit/read/readQVariantList.zig new file mode 100644 index 0000000..d29a716 --- /dev/null +++ b/src/qtshit/read/readQVariantList.zig @@ -0,0 +1,20 @@ +const std = @import("std"); +const range = @import("../utils/RangeIter.zig").range; + +const readUInt = @import("./readUInt.zig").readUInt; +const readQVariant = @import("./readQVariant.zig").readQVariant; + +const QVariant = @import("../types/QVariant.zig").QVariant; + + +pub fn readQVariantList(reader: anytype, allocator: *std.mem.Allocator) ![]QVariant { + var length = try readUInt(reader); + var variantList = try allocator.alloc(QVariant, @intCast(usize, length)); + + var iter = range(u32, 0, length); + while (iter.next()) |i| { + variantList[i] = try readQVariant(reader, allocator); + } + + return variantList; +} diff --git a/src/qtshit/read/readQVariantMap.zig b/src/qtshit/read/readQVariantMap.zig new file mode 100644 index 0000000..4281951 --- /dev/null +++ b/src/qtshit/read/readQVariantMap.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const range = @import("../utils/RangeIter.zig").range; + +const readUInt = @import("./readUInt.zig").readUInt; +const readString = @import("./readString.zig").readString; +const readQVariant = @import("./readQVariant.zig").readQVariant; + +const QVariant = @import("../types/QVariant.zig").QVariant; + + +pub fn readQVariantMap(reader: anytype, allocator: *std.mem.Allocator) !std.StringHashMap(QVariant) { + var map = std.StringHashMap(QVariant).init(allocator); + var numItems = try readUInt(reader); + + var iter = range(u32, 0, numItems); + while (iter.next()) |i| { + var key = try readString(reader, allocator); + var value = try readQVariant(reader, allocator); + try map.put(key, value); + } + + return map; +} diff --git a/src/qtshit/read/readQVariantT.zig b/src/qtshit/read/readQVariantT.zig new file mode 100644 index 0000000..1093576 --- /dev/null +++ b/src/qtshit/read/readQVariantT.zig @@ -0,0 +1,67 @@ +const std = @import("std"); + +const readInt = @import("./readInt.zig").readInt; +const readUInt = @import("./readUInt.zig").readUInt; +const readShort = @import("./readShort.zig").readShort; +const readByte = @import("./readByte.zig").readByte; +const readSignedByte = @import("./readSignedByte.zig").readSignedByte; +const readQByteArray = @import("./readQByteArray.zig").readQByteArray; +const readString = @import("./readString.zig").readString; +const readQVariantList = @import("./readQVariantList.zig").readQVariantList; +const readQVariant = @import("./readQVariant.zig").readQVariant; +const readQVariantMap = @import("./readQVariantMap.zig").readQVariantMap; +const readQStringList = @import("./readQStringList.zig").readQStringList; + +const QVariant = @import("../types/QVariant.zig").QVariant; +const QVariantTypes = @import("../types/QVariantTypes.zig").QVariantTypes; + +pub fn readQVariantT(reader: anytype, type_id: u32, allocator: *std.mem.Allocator) (@TypeOf(reader).Error || error{EndOfStream} || error{OutOfMemory})!QVariant { + switch (type_id) { + @enumToInt(QVariantTypes.Byte) => { + var byte = try readByte(reader); + return QVariant{ .Byte = byte }; + }, + @enumToInt(QVariantTypes.Int) => { + var int = try readInt(reader); + return QVariant{ .Int = int }; + }, + @enumToInt(QVariantTypes.UInt) => { + var uint = try readUInt(reader); + return QVariant{ .UInt = uint }; + }, + @enumToInt(QVariantTypes.QVariantMap) => { + var map = try readQVariantMap(reader, allocator); + return QVariant{ .QVariantMap = map }; + }, + @enumToInt(QVariantTypes.QVariantList) => { + var list = try readQVariantList(reader, allocator); + return QVariant{ .QVariantList = list }; + }, + @enumToInt(QVariantTypes.String) => { + var str = try readString(reader, allocator); + return QVariant{ .String = str }; + }, + @enumToInt(QVariantTypes.QStringList) => { + var strlist = try readQStringList(reader, allocator); + return QVariant{ .QStringList = strlist }; + }, + @enumToInt(QVariantTypes.QByteArray) => { + var bArray = try readQByteArray(reader, allocator); + return QVariant{ .QByteArray = bArray }; + }, + @enumToInt(QVariantTypes.Short) => { + var short = try readShort(reader); + return QVariant{ .Short = short }; + }, + @enumToInt(QVariantTypes.UserType) => { + var userTypeName = readQByteArray(reader, allocator); + std.debug.print("name: {s}\n", .{userTypeName}); + @panic("TODO IMPLEMENT USERTYPES."); + }, + else => { + std.debug.print("Unknown Type ID: {d}\n", .{type_id}); + @panic("Unknown Type See Above."); + }, + } + return QVariant{ .empty = true }; +} diff --git a/src/qtshit/read/readShort.zig b/src/qtshit/read/readShort.zig new file mode 100644 index 0000000..03df0f6 --- /dev/null +++ b/src/qtshit/read/readShort.zig @@ -0,0 +1,3 @@ +pub fn readShort(reader: anytype) !u16 { + return try reader.readIntBig(u16); +} diff --git a/src/qtshit/read/readSignedByte.zig b/src/qtshit/read/readSignedByte.zig new file mode 100644 index 0000000..4085455 --- /dev/null +++ b/src/qtshit/read/readSignedByte.zig @@ -0,0 +1,3 @@ +pub fn readSignedByte(reader: anytype) !i8 { + return try reader.readIntBig(i8); +} diff --git a/src/qtshit/read/readString.zig b/src/qtshit/read/readString.zig new file mode 100644 index 0000000..a06d953 --- /dev/null +++ b/src/qtshit/read/readString.zig @@ -0,0 +1,27 @@ +const std = @import("std"); +const readInt = @import("./readInt.zig").readInt; +const readShort = @import("./readShort.zig").readShort; + +pub fn readString(reader: anytype, allocator: *std.mem.Allocator) ![]u8 { + var data = std.ArrayList(u8).init(allocator); + defer data.deinit(); + + var length = try readInt(reader); + var chars = @divTrunc(length, 2); + + var index: usize = 0; + while (true) { + if (index == chars) break; + + const byte = try readShort(reader); + try data.append(@truncate(u8, byte)); + index += 1; + } + + var ut8Str = try allocator.alloc(u8, @intCast(usize, chars)); + for (data.items) |char, i| { + ut8Str[i] = char; + } + + return ut8Str; +} diff --git a/src/qtshit/read/readUInt.zig b/src/qtshit/read/readUInt.zig new file mode 100644 index 0000000..033d3cc --- /dev/null +++ b/src/qtshit/read/readUInt.zig @@ -0,0 +1,3 @@ +pub fn readUInt(reader: anytype) !u32 { + return try reader.readIntBig(u32); +} diff --git a/src/qtshit/test.zig b/src/qtshit/test.zig index 82a3fa7..ed346a2 100644 --- a/src/qtshit/test.zig +++ b/src/qtshit/test.zig @@ -127,7 +127,7 @@ test "QVariant QVariantMap serialization/deserialization" { try map.put("testkey", .{ .UInt = 1337 }); try write.writeQVariant(byteList.writer(), global_allocator, .{ - .QVariantMap = map, + .QVariantMap = map, }); var fBS = std.io.fixedBufferStream(byteList.items); @@ -136,7 +136,7 @@ test "QVariant QVariantMap serialization/deserialization" { defer qvar.freeQVariant(varient, global_allocator); var qVariantMap = varient.QVariantMap; - + var testKey = qVariantMap.get("testkey"); if (testKey) |key| { try expect(key.UInt == 1337); diff --git a/src/qtshit/types/QVariant.zig b/src/qtshit/types/QVariant.zig new file mode 100644 index 0000000..655ec8c --- /dev/null +++ b/src/qtshit/types/QVariant.zig @@ -0,0 +1,16 @@ +const std = @import("std"); +const range = @import("./rangeiter.zig").range; +const UserTypes = @import("./UserTypes.zig").UserTypes; + +pub const QVariant = union(enum) { + Int: i32, + UInt: u32, + Short: u16, + Byte: u8, + String: []const u8, + QByteArray: []u8, + QStringList: [][]const u8, + QVariantList: []QVariant, + QVariantMap: std.StringHashMap(QVariant), + UserType: UserTypes, +}; \ No newline at end of file diff --git a/src/qtshit/types/QVariantTypes.zig b/src/qtshit/types/QVariantTypes.zig new file mode 100644 index 0000000..16118b1 --- /dev/null +++ b/src/qtshit/types/QVariantTypes.zig @@ -0,0 +1,12 @@ +pub const QVariantTypes = enum(u32) { + Byte = 1, + Int = 2, + UInt = 3, + QVariantMap = 8, + QVariantList = 9, + String = 10, + QStringList = 11, + QByteArray = 12, + Short = 133, + UserType = 127, +}; diff --git a/src/qtshit/types/UserTypes.zig b/src/qtshit/types/UserTypes.zig new file mode 100644 index 0000000..77b72f9 --- /dev/null +++ b/src/qtshit/types/UserTypes.zig @@ -0,0 +1,3 @@ +pub const UserTypes = union(enum) { + NetworkId: i32, +}; diff --git a/src/qtshit/utils/QVariantTypeID.zig b/src/qtshit/utils/QVariantTypeID.zig new file mode 100644 index 0000000..2d38b58 --- /dev/null +++ b/src/qtshit/utils/QVariantTypeID.zig @@ -0,0 +1,37 @@ +const QVariant = @import("../types/QVariant.zig").QVariant; +const QVariantTypes = @import("../types/QVariantTypes.zig").QVariantTypes; + +pub fn QVariantTypeID(variant: QVariant) !u32 { + switch (variant) { + .Byte => { + return @enumToInt(QVariantTypes.Byte); + }, + .Int => { + return @enumToInt(QVariantTypes.Int); + }, + .UInt => { + return @enumToInt(QVariantTypes.UInt); + }, + .QVariantMap => { + return @enumToInt(QVariantTypes.QVariantMap); + }, + .QVariantList => { + return @enumToInt(QVariantTypes.QVariantList); + }, + .String => { + return @enumToInt(QVariantTypes.String); + }, + .QStringList => { + return @enumToInt(QVariantTypes.QStringList); + }, + .QByteArray => { + return @enumToInt(QVariantTypes.QByteArray); + }, + .Short => { + return @enumToInt(QVariantTypes.Short); + }, + .UserType => { + return @enumToInt(QVariantTypes.UserType); + }, + } +} diff --git a/src/qtshit/rangeiter.zig b/src/qtshit/utils/RangeIter.zig similarity index 100% rename from src/qtshit/rangeiter.zig rename to src/qtshit/utils/RangeIter.zig diff --git a/src/qtshit/utils/freeQVariant.zig b/src/qtshit/utils/freeQVariant.zig new file mode 100644 index 0000000..bfc0688 --- /dev/null +++ b/src/qtshit/utils/freeQVariant.zig @@ -0,0 +1,43 @@ +const std = @import("std"); +const QVariant = @import("../types/QVariant.zig").QVariant; + +pub fn freeQVariant(variant: QVariant, allocator: *std.mem.Allocator) void { + switch (variant) { + .Byte, .Int, .UInt, .Short => { + // Static + }, + + .QVariantMap => |q| { + var qMapIter = q.iterator(); + while (qMapIter.next()) |v| { + allocator.free(v.key); + freeQVariant(v.value, allocator); + } + // Compiler bug maybe? doesnt want me to drop const so have to store it in a variable + var qi = q; + qi.deinit(); + }, + + .QVariantList => |l| { + for (l) |varient, i| { + freeQVariant(varient, allocator); + } + allocator.free(l); + }, + .String => |s| { + allocator.free(s); + }, + .QStringList => |l| { + for (l) |varient, i| { + allocator.free(varient); + } + allocator.free(l); + }, + .QByteArray => |ba| { + allocator.free(ba); + }, + .UserType => { + @panic("Do Not Know How?????"); + }, + } +} diff --git a/src/qtshit/utils/prettyPrintQVariant.zig b/src/qtshit/utils/prettyPrintQVariant.zig new file mode 100644 index 0000000..b9f261a --- /dev/null +++ b/src/qtshit/utils/prettyPrintQVariant.zig @@ -0,0 +1,64 @@ +const std = @import("std"); +const QVariant = @import("../types/QVariant.zig").QVariant; +const range = @import("../utils/RangeIter.zig").range; + +pub fn print_indent_level(indentLevel: u64) void { + var iter = range(u64, 0, indentLevel); + while (iter.next()) |i| { + std.debug.print(" ", .{}); + } +} + +pub fn prettyPrintQVariant(variant: QVariant, indentLevel: u64) void { + print_indent_level(indentLevel); + + switch (variant) { + .Byte => |b| { + std.debug.print("Byte: {d}\n", .{b}); + }, + .Int => |i| { + std.debug.print("Int: {d}\n", .{i}); + }, + .UInt => |i| { + std.debug.print("UInt: {d}\n", .{i}); + }, + .QVariantMap => |q| { + std.debug.print("QVariantMap:\n", .{}); + var qMapIter = q.iterator(); + while (qMapIter.next()) |v| { + print_indent_level(indentLevel + 1); + std.debug.print("Key: \"{s}\"\n", .{v.key}); + print_indent_level(indentLevel + 1); + std.debug.print("Value:\n", .{}); + prettyPrintQVariant(v.value, indentLevel + 2); + } + }, + .QVariantList => |l| { + std.debug.print("QVariantList:\n", .{}); + + for (l) |varient, i| { + print_indent_level(indentLevel + 1); + std.debug.print("Item #{d}\n", .{i}); + prettyPrintQVariant(varient, indentLevel + 2); + } + }, + .String => |s| { + std.debug.print("String: \"{s}\"\n", .{s}); + }, + .QStringList => |l| { + std.debug.print("QStringList:\n", .{}); + + for (l) |str, i| { + print_indent_level(indentLevel + 1); + std.debug.print("\"{s}\" \n", .{str}); + } + }, + .QByteArray => {}, + .Short => |s| { + std.debug.print("Short: \"{d}\"\n", .{s}); + }, + .UserType => { + @panic("HOW PRINT?????"); + }, + } +} diff --git a/src/qtshit/write.zig b/src/qtshit/write.zig index 999c488..9216350 100644 --- a/src/qtshit/write.zig +++ b/src/qtshit/write.zig @@ -1,5 +1,6 @@ const std = @import("std"); -const qvar = @import("./qvariant.zig"); +const QVariantType = @import("./types/QVariant.zig").QVariant; +const QVariantTypeID = @import("./utils/QVariantTypeID.zig").QVariantTypeID; const AllKnownErrors = (std.os.WriteError || error{OutOfMemory}); @@ -42,14 +43,14 @@ pub fn writeQStringList(writer: anytype, allocator: *std.mem.Allocator, strList: } } -pub fn writeQVariantList(writer: anytype, allocator: *std.mem.Allocator, varList: []qvar.QVariant) AllKnownErrors!void { +pub fn writeQVariantList(writer: anytype, allocator: *std.mem.Allocator, varList: []QVariantType) AllKnownErrors!void { try writeUInt(writer, @intCast(u32, varList.len)); for (varList) |v| { try writeQVariant(writer, allocator, v); } } -pub fn writeQVariantMap(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(qvar.QVariant)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void { +pub fn writeQVariantMap(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(QVariantType)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void { var data = std.ArrayList(u8).init(allocator); defer data.deinit(); @@ -71,8 +72,8 @@ pub fn writeQVariantHeader(writer: anytype, type_id: u32) !void { try writeByte(writer, 0); } -pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: qvar.QVariant) !void { - try writeQVariantHeader(writer, try qvar.qvariant_type_id(variant)); +pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: QVariantType) !void { + try writeQVariantHeader(writer, try QVariantTypeID(variant)); switch (variant) { .Byte => |out| { try writeByte(writer, out); @@ -101,13 +102,16 @@ pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: qv .Short => |out| { try writeShort(writer, out); }, + .UserType => { + @panic("Can't write UserTypes"); + }, //else => { // @panic("Unsupported!"); //}, } } -pub fn writeFrame(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(qvar.QVariant)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void { +pub fn writeFrame(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(QVariantType)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void { var data = std.ArrayList(u8).init(allocator); try writeQVariant(data.writer(), allocator, .{ .QVariantMap = map,