Add BufferManager and fix all memory leaks.
This commit is contained in:
parent
cb88f3c3b3
commit
82e3e8491c
37
src/BufferManager.zig
Normal file
37
src/BufferManager.zig
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const BufferInfo = @import("./qtshit/types/UserType.zig").BufferInfo;
|
||||||
|
|
||||||
|
pub const BufferManager = struct {
|
||||||
|
allocator: *std.mem.Allocator,
|
||||||
|
buffers: std.ArrayList(BufferInfo),
|
||||||
|
|
||||||
|
pub fn addBufferInfo(s: *BufferManager, bufferInfo: BufferInfo) !void {
|
||||||
|
try s.buffers.append(BufferInfo{
|
||||||
|
.ID = bufferInfo.ID,
|
||||||
|
.NetworkID = bufferInfo.NetworkID,
|
||||||
|
.Type = bufferInfo.Type,
|
||||||
|
.Name = try s.allocator.dupe(u8, bufferInfo.Name),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pub fn getFirstByName(s: *BufferManager, name: []const u8) !?BufferInfo {
|
||||||
|
for (s.buffers.items) |item| {
|
||||||
|
if (std.mem.eql(u8, item.Name, name)) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
pub fn deinit(s: *BufferManager, ) void {
|
||||||
|
for (s.buffers.items) |item| {
|
||||||
|
s.allocator.free(item.Name);
|
||||||
|
}
|
||||||
|
s.buffers.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn initBufferManager(allocator: *std.mem.Allocator) BufferManager {
|
||||||
|
return BufferManager{
|
||||||
|
.allocator = allocator,
|
||||||
|
.buffers = std.ArrayList(BufferInfo).init(allocator),
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const BufferManager = @import("./BufferManager.zig");
|
||||||
|
|
||||||
const read = @import("./qtshit/read.zig");
|
const read = @import("./qtshit/read.zig");
|
||||||
const write = @import("./qtshit/write.zig");
|
const write = @import("./qtshit/write.zig");
|
||||||
const range = @import("./qtshit/utils/RangeIter.zig").range;
|
const range = @import("./qtshit/utils/RangeIter.zig").range;
|
||||||
|
@ -6,6 +9,8 @@ const QVariantType = @import("./qtshit/types/QVariant.zig").QVariant;
|
||||||
const prettyPrintQVariant = @import("./qtshit/utils/prettyPrintQVariant.zig").prettyPrintQVariant;
|
const prettyPrintQVariant = @import("./qtshit/utils/prettyPrintQVariant.zig").prettyPrintQVariant;
|
||||||
const freeQVariant = @import("./qtshit/utils/free/freeQVariant.zig").freeQVariant;
|
const freeQVariant = @import("./qtshit/utils/free/freeQVariant.zig").freeQVariant;
|
||||||
const QVariantMapToQVariantList = @import("./qtshit/utils/QVariantMapToQVariantList.zig").QVariantMapToQVariantList;
|
const QVariantMapToQVariantList = @import("./qtshit/utils/QVariantMapToQVariantList.zig").QVariantMapToQVariantList;
|
||||||
|
const UserType = @import("./qtshit/types/UserType.zig");
|
||||||
|
|
||||||
const tls = @import("./deps/iguanaTLS/src/main.zig");
|
const tls = @import("./deps/iguanaTLS/src/main.zig");
|
||||||
|
|
||||||
fn dumpDebug(name: []const u8, list: std.ArrayList(u8)) !void {
|
fn dumpDebug(name: []const u8, list: std.ArrayList(u8)) !void {
|
||||||
|
@ -23,6 +28,7 @@ fn dumpDebug(name: []const u8, list: std.ArrayList(u8)) !void {
|
||||||
pub const Client = struct {
|
pub const Client = struct {
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
stream: *std.net.Stream,
|
stream: *std.net.Stream,
|
||||||
|
bufferManager: BufferManager.BufferManager,
|
||||||
|
|
||||||
pub var tlsAllowed = !true;
|
pub var tlsAllowed = !true;
|
||||||
pub var tlsConnected = !true;
|
pub var tlsConnected = !true;
|
||||||
|
@ -30,6 +36,11 @@ pub const Client = struct {
|
||||||
pub const TLSStream = tls.Client(std.net.Stream.Reader, std.net.Stream.Writer, tls.ciphersuites.all, false);
|
pub const TLSStream = tls.Client(std.net.Stream.Reader, std.net.Stream.Writer, tls.ciphersuites.all, false);
|
||||||
pub var tlsClient: TLSStream = undefined;
|
pub var tlsClient: TLSStream = undefined;
|
||||||
|
|
||||||
|
pub fn deinit(s: *Client) void {
|
||||||
|
s.bufferManager.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn initTLS(s: *Client) !void {
|
pub fn initTLS(s: *Client) !void {
|
||||||
if (!tlsConnected and tlsAllowed) {
|
if (!tlsConnected and tlsAllowed) {
|
||||||
var randBuf: [32]u8 = undefined;
|
var randBuf: [32]u8 = undefined;
|
||||||
|
@ -84,6 +95,7 @@ pub const Client = struct {
|
||||||
pub fn readFrame(s: *Client) !QVariantType {
|
pub fn readFrame(s: *Client) !QVariantType {
|
||||||
try s.initTLS();
|
try s.initTLS();
|
||||||
var data: std.ArrayList(u8) = undefined;
|
var data: std.ArrayList(u8) = undefined;
|
||||||
|
defer data.deinit();
|
||||||
|
|
||||||
if (tlsConnected) {
|
if (tlsConnected) {
|
||||||
var reader = tlsClient.reader();
|
var reader = tlsClient.reader();
|
||||||
|
@ -112,18 +124,22 @@ pub const Client = struct {
|
||||||
}
|
}
|
||||||
pub fn quassel_init_packet(s: *Client) !void {
|
pub fn quassel_init_packet(s: *Client) !void {
|
||||||
var data = std.ArrayList(u8).init(s.allocator);
|
var data = std.ArrayList(u8).init(s.allocator);
|
||||||
|
defer data.deinit();
|
||||||
|
|
||||||
var map = std.StringHashMap(QVariantType).init(s.allocator);
|
var map = std.StringHashMap(QVariantType).init(s.allocator);
|
||||||
|
defer map.deinit();
|
||||||
|
|
||||||
try map.put("MsgType", .{ .String = "ClientInit" });
|
try map.put("MsgType", .{ .String = "ClientInit" });
|
||||||
try map.put("UseCompression", .{ .UInt = 0 });
|
try map.put("UseCompression", .{ .UInt = 0 });
|
||||||
try map.put("UseSsl", .{ .UInt = 1 });
|
try map.put("UseSsl", .{ .UInt = 1 });
|
||||||
|
|
||||||
try map.put("ProtocolVersion", .{ .UInt = 10 });
|
try map.put("ProtocolVersion", .{ .UInt = 10 });
|
||||||
try map.put("ClientVersion", .{ .String = "0.1 (quasselclient)" });
|
try map.put("ClientVersion", .{ .String = "0.1 (quasselclient)" });
|
||||||
try map.put("ClientDate", .{ .String = "Wed, 02 Jun 2021 17:30:30 +0100" });
|
try map.put("ClientDate", .{ .String = "Wed, 02 Jun 2021 17:30:30 +0100" });
|
||||||
try map.put("Features", .{ .Int = 0x00008000 });
|
try map.put("Features", .{ .Int = 0x00008000 });
|
||||||
|
|
||||||
var featureList = std.ArrayList([]const u8).init(s.allocator);
|
var featureList = std.ArrayList([]const u8).init(s.allocator);
|
||||||
defer featureList.deinit();
|
defer featureList.deinit();
|
||||||
|
|
||||||
try featureList.append("LongTime");
|
try featureList.append("LongTime");
|
||||||
try featureList.append("LongMessageID");
|
try featureList.append("LongMessageID");
|
||||||
try featureList.append("SenderPrefixes");
|
try featureList.append("SenderPrefixes");
|
||||||
|
@ -137,16 +153,18 @@ pub const Client = struct {
|
||||||
|
|
||||||
try s.writeFrame(data);
|
try s.writeFrame(data);
|
||||||
|
|
||||||
var varient = try s.readFrame();
|
var variant = try s.readFrame();
|
||||||
prettyPrintQVariant(varient, 0);
|
defer freeQVariant(variant, s.allocator);
|
||||||
tlsAllowed = varient.QVariantMap.get("SupportSsl").?.Byte == 1;
|
tlsAllowed = variant.QVariantMap.get("SupportSsl").?.Byte == 1;
|
||||||
freeQVariant(varient, s.allocator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn quassel_login(s: *Client, username: []const u8, password: []const u8) !void {
|
pub fn quassel_login(s: *Client, username: []const u8, password: []const u8) !void {
|
||||||
var data = std.ArrayList(u8).init(s.allocator);
|
var data = std.ArrayList(u8).init(s.allocator);
|
||||||
|
defer data.deinit();
|
||||||
|
|
||||||
var map = std.StringHashMap(QVariantType).init(s.allocator);
|
var map = std.StringHashMap(QVariantType).init(s.allocator);
|
||||||
|
defer map.deinit();
|
||||||
|
|
||||||
try map.put("MsgType", .{ .String = "ClientLogin" });
|
try map.put("MsgType", .{ .String = "ClientLogin" });
|
||||||
try map.put("User", .{ .String = username });
|
try map.put("User", .{ .String = username });
|
||||||
try map.put("Password", .{ .String = password });
|
try map.put("Password", .{ .String = password });
|
||||||
|
@ -156,13 +174,61 @@ pub const Client = struct {
|
||||||
});
|
});
|
||||||
|
|
||||||
try s.writeFrame(data);
|
try s.writeFrame(data);
|
||||||
|
|
||||||
|
var loginResponse = try s.readFrame();
|
||||||
|
defer freeQVariant(loginResponse, s.allocator);
|
||||||
|
|
||||||
|
var loginResponseMap = loginResponse.QVariantMap;
|
||||||
|
if (loginResponseMap.get("MsgType")) |msgType| {
|
||||||
|
if (std.mem.eql(u8, msgType.String, "ClientLoginReject")) {
|
||||||
|
return error.InvalidLogin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_session_init_packet(s: *Client, sessionState: std.StringHashMap(QVariantType)) !void {
|
||||||
|
for (sessionState.get("BufferInfos").?.QVariantList) |qvar| {
|
||||||
|
try s.bufferManager.addBufferInfo(qvar.UserType.BufferInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_quassel_packet(s: *Client) !void {
|
pub fn read_quassel_packet(s: *Client) !void {
|
||||||
std.debug.print("\n\nQuassel Packet: \n", .{});
|
var variant = try s.readFrame();
|
||||||
var varient = try s.readFrame();
|
defer freeQVariant(variant, s.allocator);
|
||||||
prettyPrintQVariant(varient, 0);
|
|
||||||
freeQVariant(varient, s.allocator);
|
switch (variant) {
|
||||||
|
.QVariantMap => |map| {
|
||||||
|
if (map.get("MsgType")) |msgType| {
|
||||||
|
if (std.mem.eql(u8, msgType.String, "SessionInit")) {
|
||||||
|
var sessionState = map.get("SessionState").?.QVariantMap;
|
||||||
|
try s.handle_session_init_packet(sessionState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
std.debug.print("\n\n Unknown: Quassel Packet: \n", .{});
|
||||||
|
prettyPrintQVariant(variant, 0);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_message(s: *Client, bufferInfo: UserType.BufferInfo, message: []const u8) !void {
|
||||||
|
var data = std.ArrayList(u8).init(s.allocator);
|
||||||
|
defer data.deinit();
|
||||||
|
|
||||||
|
var listItems = std.ArrayList(QVariantType).init(s.allocator);
|
||||||
|
defer listItems.deinit();
|
||||||
|
|
||||||
|
try listItems.append(.{ .Int = 2 });
|
||||||
|
try listItems.append(.{ .QByteArray = "2sendInput(BufferInfo,QString)" });
|
||||||
|
try listItems.append(.{ .UserType = .{ .BufferInfo = bufferInfo } });
|
||||||
|
try listItems.append(.{ .String = message });
|
||||||
|
|
||||||
|
try write.writeQVariant(data.writer(), s.allocator, .{
|
||||||
|
.QVariantList = listItems.items,
|
||||||
|
});
|
||||||
|
|
||||||
|
try s.writeFrame(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,5 +236,6 @@ pub fn initClient(allocator: *std.mem.Allocator, stream: *std.net.Stream) Client
|
||||||
return Client{
|
return Client{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.stream = stream,
|
.stream = stream,
|
||||||
|
.bufferManager = BufferManager.initBufferManager(allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
39
src/main.zig
39
src/main.zig
|
@ -1,30 +1,40 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const read = @import("./qtshit/read.zig");
|
const DebugAllocator = @import("./debug_allocator.zig");
|
||||||
const write = @import("./qtshit/write.zig");
|
const write = @import("./qtshit/write.zig");
|
||||||
|
|
||||||
const initClient = @import("./client.zig").initClient;
|
const initClient = @import("./client.zig").initClient;
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn realMain(allocator: *std.mem.Allocator) !void {
|
||||||
const allocator = std.heap.page_allocator;
|
|
||||||
|
|
||||||
var argIter = std.process.args();
|
var argIter = std.process.args();
|
||||||
_ = try argIter.next(allocator).?;
|
|
||||||
|
allocator.free(try argIter.next(allocator).?);
|
||||||
|
|
||||||
var host = try argIter.next(allocator).?;
|
var host = try argIter.next(allocator).?;
|
||||||
|
defer allocator.free(host);
|
||||||
var port = try argIter.next(allocator).?;
|
var port = try argIter.next(allocator).?;
|
||||||
|
defer allocator.free(port);
|
||||||
var portInt = try std.fmt.parseInt(u16, port, 10);
|
var portInt = try std.fmt.parseInt(u16, port, 10);
|
||||||
var username = try argIter.next(allocator).?;
|
var username = try argIter.next(allocator).?;
|
||||||
|
defer allocator.free(username);
|
||||||
var password = try argIter.next(allocator).?;
|
var password = try argIter.next(allocator).?;
|
||||||
|
defer allocator.free(password);
|
||||||
|
|
||||||
std.debug.print("host={s} port={d}\n", .{ host, portInt });
|
std.debug.print("host={s} port={d}\n", .{ host, portInt });
|
||||||
|
|
||||||
while (true) {
|
|
||||||
var sock = try std.net.tcpConnectToHost(allocator, host, portInt);
|
var sock = try std.net.tcpConnectToHost(allocator, host, portInt);
|
||||||
|
|
||||||
var client = initClient(allocator, &sock);
|
var client = initClient(allocator, &sock);
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
try client.handshake();
|
try client.handshake();
|
||||||
try client.quassel_init_packet();
|
try client.quassel_init_packet();
|
||||||
try client.quassel_login(username, password);
|
try client.quassel_login(username, password);
|
||||||
|
|
||||||
|
_ = try client.read_quassel_packet();
|
||||||
|
|
||||||
|
var bufferInfo = try client.bufferManager.getFirstByName("z_is_stimky");
|
||||||
|
try client.send_message(bufferInfo.?, "uwu, owo, uwu");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
client.read_quassel_packet() catch |err| {
|
client.read_quassel_packet() catch |err| {
|
||||||
if (err == error.DecodeError) {
|
if (err == error.DecodeError) {
|
||||||
|
@ -32,11 +42,22 @@ pub fn main() !void {
|
||||||
} else if (err == error.EndOfStream) {
|
} else if (err == error.EndOfStream) {
|
||||||
std.debug.print("EOS.\n", .{});
|
std.debug.print("EOS.\n", .{});
|
||||||
std.time.sleep(1000 * std.time.ns_per_ms);
|
std.time.sleep(1000 * std.time.ns_per_ms);
|
||||||
continue;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpalloc = std.heap.GeneralPurposeAllocator(.{
|
||||||
|
.stack_trace_frames = 20,
|
||||||
|
}){};
|
||||||
|
defer std.debug.assert(!gpalloc.deinit());
|
||||||
|
|
||||||
|
const alloc = &gpalloc.allocator;
|
||||||
|
|
||||||
|
try realMain(alloc);
|
||||||
|
}
|
||||||
|
|
|
@ -12,8 +12,9 @@ const readMessage = @import("./readMessage.zig").readMessage;
|
||||||
|
|
||||||
pub fn readUserType(reader: anytype, allocator: *std.mem.Allocator) !UserType {
|
pub fn readUserType(reader: anytype, allocator: *std.mem.Allocator) !UserType {
|
||||||
var userTypeName = try readQByteArray(reader, allocator);
|
var userTypeName = try readQByteArray(reader, allocator);
|
||||||
|
defer allocator.free(userTypeName);
|
||||||
|
|
||||||
userTypeName = userTypeName[0 .. userTypeName.len - 1];
|
userTypeName = userTypeName[0 .. userTypeName.len - 1];
|
||||||
//std.debug.print("read: readUserType name={s} \n", .{userTypeName});
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, userTypeName, "BufferId")) {
|
if (std.mem.eql(u8, userTypeName, "BufferId")) {
|
||||||
return UserType{
|
return UserType{
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub const QVariant = union(enum) {
|
||||||
Short: u16,
|
Short: u16,
|
||||||
Byte: u8,
|
Byte: u8,
|
||||||
String: []const u8,
|
String: []const u8,
|
||||||
QByteArray: []u8,
|
QByteArray: []const u8,
|
||||||
QStringList: [][]const u8,
|
QStringList: [][]const u8,
|
||||||
QVariantList: []QVariant,
|
QVariantList: []QVariant,
|
||||||
QVariantMap: std.StringHashMap(QVariant),
|
QVariantMap: std.StringHashMap(QVariant),
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub const BufferInfo = struct {
|
||||||
ID: i32,
|
ID: i32,
|
||||||
NetworkID: i32,
|
NetworkID: i32,
|
||||||
Type: u16,
|
Type: u16,
|
||||||
Name: []u8,
|
Name: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Message = struct {
|
pub const Message = struct {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn freeQByteArray(qbytearray: []u8, allocator: *std.mem.Allocator) void {
|
pub fn freeQByteArray(qbytearray: []const u8, allocator: *std.mem.Allocator) void {
|
||||||
allocator.free(qbytearray);
|
allocator.free(qbytearray);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,22 +43,27 @@ pub fn prettyPrintUserType(usertype: UserType, indentLevel: u64) void {
|
||||||
},
|
},
|
||||||
.IrcUser => |value| {
|
.IrcUser => |value| {
|
||||||
std.debug.print("IrcUser:\n", .{});
|
std.debug.print("IrcUser:\n", .{});
|
||||||
|
print_indent_level(indentLevel + 1);
|
||||||
prettyPrintQVariantMap(value, indentLevel + 1);
|
prettyPrintQVariantMap(value, indentLevel + 1);
|
||||||
},
|
},
|
||||||
.IrcChannel => |value| {
|
.IrcChannel => |value| {
|
||||||
std.debug.print("IrcChannel:\n", .{});
|
std.debug.print("IrcChannel:\n", .{});
|
||||||
|
print_indent_level(indentLevel + 1);
|
||||||
prettyPrintQVariantMap(value, indentLevel + 1);
|
prettyPrintQVariantMap(value, indentLevel + 1);
|
||||||
},
|
},
|
||||||
.Identity => |value| {
|
.Identity => |value| {
|
||||||
std.debug.print("Identity:\n", .{});
|
std.debug.print("Identity:\n", .{});
|
||||||
|
print_indent_level(indentLevel + 1);
|
||||||
prettyPrintQVariantMap(value, indentLevel + 1);
|
prettyPrintQVariantMap(value, indentLevel + 1);
|
||||||
},
|
},
|
||||||
.NetworkInfo => |value| {
|
.NetworkInfo => |value| {
|
||||||
std.debug.print("NetworkInfo:\n", .{});
|
std.debug.print("NetworkInfo:\n", .{});
|
||||||
|
print_indent_level(indentLevel + 1);
|
||||||
prettyPrintQVariantMap(value, indentLevel + 1);
|
prettyPrintQVariantMap(value, indentLevel + 1);
|
||||||
},
|
},
|
||||||
.NetworkServer => |value| {
|
.NetworkServer => |value| {
|
||||||
std.debug.print("NetworkServer:\n", .{});
|
std.debug.print("NetworkServer:\n", .{});
|
||||||
|
print_indent_level(indentLevel + 1);
|
||||||
prettyPrintQVariantMap(value, indentLevel + 1);
|
prettyPrintQVariantMap(value, indentLevel + 1);
|
||||||
},
|
},
|
||||||
.BufferInfo => |value| {
|
.BufferInfo => |value| {
|
||||||
|
@ -106,7 +111,6 @@ pub fn prettyPrintUserType(usertype: UserType, indentLevel: u64) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prettyPrintQVariantMap(qvariantmap: std.StringHashMap(QVariant), indentLevel: u64) void {
|
pub fn prettyPrintQVariantMap(qvariantmap: std.StringHashMap(QVariant), indentLevel: u64) void {
|
||||||
print_indent_level(indentLevel);
|
|
||||||
std.debug.print("QVariantMap:\n", .{});
|
std.debug.print("QVariantMap:\n", .{});
|
||||||
var qMapIter = qvariantmap.iterator();
|
var qMapIter = qvariantmap.iterator();
|
||||||
while (qMapIter.next()) |v| {
|
while (qMapIter.next()) |v| {
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub fn utf16BEToUtf8(allocator: *std.mem.Allocator, utf16: []u16) ![]u8 {
|
||||||
// Big Endian to Little Endian
|
// Big Endian to Little Endian
|
||||||
var utf16LE = byteSwapArray(u16, &utf16BE);
|
var utf16LE = byteSwapArray(u16, &utf16BE);
|
||||||
|
|
||||||
var utf8 = try std.unicode.utf16leToUtf8AllocZ(allocator, utf16LE);
|
var utf8 = try std.unicode.utf16leToUtf8Alloc(allocator, utf16LE);
|
||||||
return utf8;
|
return utf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
src/qtshit/write/usertypes/writeBufferInfo.zig
Normal file
19
src/qtshit/write/usertypes/writeBufferInfo.zig
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const BufferInfo = @import("../../types/UserType.zig").BufferInfo;
|
||||||
|
const writeInt = @import("../writeInt.zig").writeInt;
|
||||||
|
const writeShort = @import("../writeShort.zig").writeShort;
|
||||||
|
const writeByte = @import("../writeByte.zig").writeByte;
|
||||||
|
const writeQByteArray = @import("../writeQByteArray.zig").writeQByteArray;
|
||||||
|
|
||||||
|
pub fn writeBufferInfo(writer: anytype, bufferInfo: BufferInfo) !void {
|
||||||
|
try writeQByteArray(writer, "BufferInfo\x00");
|
||||||
|
try writeInt(writer, bufferInfo.ID);
|
||||||
|
try writeInt(writer, bufferInfo.NetworkID);
|
||||||
|
try writeShort(writer, bufferInfo.Type);
|
||||||
|
// 4 undocumented bytes.
|
||||||
|
try writeByte(writer, 0x00);
|
||||||
|
try writeByte(writer, 0x00);
|
||||||
|
try writeByte(writer, 0x00);
|
||||||
|
try writeByte(writer, 0x00);
|
||||||
|
try writeQByteArray(writer, bufferInfo.Name);
|
||||||
|
}
|
14
src/qtshit/write/usertypes/writeUserType.zig
Normal file
14
src/qtshit/write/usertypes/writeUserType.zig
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const UserType = @import("../../types/UserType.zig").UserType;
|
||||||
|
const writeBufferInfo = @import("./writeBufferInfo.zig").writeBufferInfo;
|
||||||
|
|
||||||
|
pub fn writeUserType(writer: anytype, allocator: *std.mem.Allocator, usertype: UserType) !void {
|
||||||
|
switch (usertype) {
|
||||||
|
.BufferInfo => |value| {
|
||||||
|
try writeBufferInfo(writer, value);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
@panic("Unsupported!");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,8 @@ const writeQVariantList = @import("./writeQVariantList.zig").writeQVariantList;
|
||||||
const writeQVariantHeader = @import("./writeQVariantHeader.zig").writeQVariantHeader;
|
const writeQVariantHeader = @import("./writeQVariantHeader.zig").writeQVariantHeader;
|
||||||
const writeQVariantMap = @import("./writeQVariantMap.zig").writeQVariantMap;
|
const writeQVariantMap = @import("./writeQVariantMap.zig").writeQVariantMap;
|
||||||
const writeQStringList = @import("./writeQStringList.zig").writeQStringList;
|
const writeQStringList = @import("./writeQStringList.zig").writeQStringList;
|
||||||
|
const writeUserType = @import("./usertypes/writeUserType.zig").writeUserType;
|
||||||
|
|
||||||
|
|
||||||
pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: QVariantType) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory} || error{InvalidUtf8})!void {
|
pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: QVariantType) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory} || error{InvalidUtf8})!void {
|
||||||
try writeQVariantHeader(writer, try QVariantTypeID(variant));
|
try writeQVariantHeader(writer, try QVariantTypeID(variant));
|
||||||
|
@ -47,8 +49,8 @@ pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: QV
|
||||||
.QDateTime => {
|
.QDateTime => {
|
||||||
@panic("Can't write QDateTime");
|
@panic("Can't write QDateTime");
|
||||||
},
|
},
|
||||||
.UserType => {
|
.UserType => |out| {
|
||||||
@panic("Can't write UserTypes");
|
try writeUserType(writer, allocator, out);
|
||||||
},
|
},
|
||||||
//else => {
|
//else => {
|
||||||
// @panic("Unsupported!");
|
// @panic("Unsupported!");
|
||||||
|
|
Loading…
Reference in a new issue