1
0
Fork 0
QuasselClient/src/qtshit/read.zig
2021-06-02 15:31:51 +01:00

118 lines
3.7 KiB
Zig

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);
}
pub fn get_short(reader: anytype) !u16 {
return try reader.readIntBig(u16);
}
pub fn get_byte(reader: anytype) !u8 {
return try reader.readByte();
}
pub fn get_bytearray(reader: anytype, allocator: *std.mem.Allocator) !std.ArrayList(u8) {
var byteList = std.ArrayList(u8).init(allocator);
var length = try get_int(reader);
var index: usize = 0;
while (true) {
if (index == length) return byteList;
const byte = try reader.readByte();
try byteList.append(byte);
index += 1;
}
}
pub fn get_string(reader: anytype, allocator: *std.mem.Allocator) ![]u8 {
var data = std.ArrayList(u8).init(allocator);
defer data.deinit();
var length = try reader.readIntBig(i32);
var index: usize = 0;
while (true) {
if (index == length) break;
const byte = try reader.readIntBig(u16);
try data.append(@intCast(u8, byte));
index += 1;
}
var ut8Str = try allocator.alloc(u8, @intCast(usize, length));
for (data.items) |char, i| {
ut8Str[i] = char;
}
return ut8Str;
}
pub fn get_stringlist(reader: anytype, allocator: *std.mem.Allocator) !std.ArrayList([]const u8) {
var strList = std.ArrayList([]const u8).init(allocator);
var size = try get_int(reader);
var i: u32 = 0;
while (i < size) {
try strList.append(try get_string(reader, allocator));
i = i + 1;
}
return strList;
}
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);
return qvar.QVariant{ .byte = byte };
},
@enumToInt(qvar.QVariantTypes.int_1), @enumToInt(qvar.QVariantTypes.int_2) => {
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 };
},
@enumToInt(qvar.QVariantTypes.stringlist) => {
var strlist = try get_stringlist(reader, allocator);
return qvar.QVariant{ .stringlist = strlist };
},
@enumToInt(qvar.QVariantTypes.bytearray) => {
var bArray = try get_bytearray(reader, allocator);
return qvar.QVariant{ .bytearray = bArray };
},
@enumToInt(qvar.QVariantTypes.short) => {
var short = try get_short(reader);
return qvar.QVariant{ .short = short };
},
else => {},
}
return qvar.QVariant{ .empty = true };
}
pub fn get_variant(reader: anytype, allocator: *std.mem.Allocator) !qvar.QVariant {
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;
}