118 lines
3.7 KiB
Zig
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;
|
|
}
|