Add some unicode things.

This commit is contained in:
Kitteh 2021-06-04 12:33:13 +01:00
parent 04385070f1
commit cb7afda2c8
8 changed files with 55 additions and 162 deletions

View file

@ -61,9 +61,9 @@ pub const Client = struct {
try dumpDebug("ClientInit.bin", list);
try s.stream.writer().writeAll(list.items);
std.debug.print("\n\nInitPacket: \n", .{});
//std.debug.print("\n\nInitPacket: \n", .{});
prettyPrintQVariant(.{ .QVariantMap = map }, 0);
//prettyPrintQVariant(.{ .QVariantMap = map }, 0);
try s.read_quassel_packet();
}

View file

@ -1,147 +0,0 @@
const std = @import("std");
const expect = std.testing.expect;
const global_allocator = std.testing.allocator;
const read = @import("./read.zig");
const write = @import("./write.zig");
const QVariant = @import("./types/QVariant.zig").QVariant;
const freeQVariant = @import("./utils/freeQVariant.zig").freeQVariant;
test "UInt serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
try write.writeUInt(byteList.writer(), 4242);
var fBS = std.io.fixedBufferStream(byteList.items);
var val = try read.readUInt(fBS.reader());
try expect(val == 4242);
}
test "Short serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
try write.writeShort(byteList.writer(), 6969);
var fBS = std.io.fixedBufferStream(byteList.items);
var val = try read.readShort(fBS.reader());
try expect(val == 6969);
}
test "Byte serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
try write.writeByte(byteList.writer(), 'a');
var fBS = std.io.fixedBufferStream(byteList.items);
var val = try read.readByte(fBS.reader());
try expect(val == 'a');
}
test "String serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
var arr = "Hello World!".*;
try write.writeString(byteList.writer(), global_allocator, &arr);
var fBS = std.io.fixedBufferStream(byteList.items);
var val = try read.readString(fBS.reader(), global_allocator);
defer global_allocator.free(val);
try std.testing.expectEqualStrings("Hello World!", val);
}
test "QByteArray serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
var arr = std.ArrayList(u8).init(global_allocator);
defer arr.deinit();
try arr.append(13);
try arr.append(12);
try write.writeQByteArray(byteList.writer(), arr.items);
var fBS = std.io.fixedBufferStream(byteList.items);
var val = try read.readQByteArray(fBS.reader(), global_allocator);
defer global_allocator.free(val);
try expect(arr.items.len == val.len);
for (arr.items) |item, index| {
try std.testing.expect(item == val[index]);
}
}
test "QStringList serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
var arr = std.ArrayList([]const u8).init(global_allocator);
defer arr.deinit();
try arr.append("Hewwo");
try arr.append("World");
try write.writeQStringList(byteList.writer(), global_allocator, arr.items);
var fBS = std.io.fixedBufferStream(byteList.items);
var val = try read.readQStringList(fBS.reader(), global_allocator);
defer {
for (val) |str| {
global_allocator.free(str);
}
global_allocator.free(val);
}
try expect(arr.items.len == val.len);
for (arr.items) |str, index| {
try std.testing.expectEqualStrings(str, val[index]);
}
}
test "QVariant UInt serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
// ACAB
try write.writeQVariant(byteList.writer(), global_allocator, .{ .UInt = 1312 });
var fBS = std.io.fixedBufferStream(byteList.items);
var variant = try read.readQVariant(fBS.reader(), global_allocator);
try expect(variant.UInt == 1312);
}
test "QVariant QVariantMap serialization/deserialization" {
var byteList = std.ArrayList(u8).init(global_allocator);
defer byteList.deinit();
var map = std.StringHashMap(QVariant).init(global_allocator);
defer map.deinit();
try map.put("testkey", .{ .UInt = 1337 });
try write.writeQVariant(byteList.writer(), global_allocator, .{
.QVariantMap = map,
});
var fBS = std.io.fixedBufferStream(byteList.items);
var varient = try read.readQVariant(fBS.reader(), global_allocator);
defer freeQVariant(varient, global_allocator);
var qVariantMap = varient.QVariantMap;
var testKey = qVariantMap.get("testkey");
if (testKey) |key| {
try expect(key.UInt == 1337);
} else {
try expect(!true);
}
}

View file

@ -0,0 +1,43 @@
const std = @import("std");
const testing = std.testing;
// Operates on the pointer you give it, doing the byte swaps in place.
// Returns deref'd pointer for convinience.
pub fn byteSwapArray(comptime T: type, ptr: *[]T) []T {
for (ptr.*) |byte, index| {
ptr.*[index] = @byteSwap(T, byte);
}
return ptr.*;
}
pub fn utf8ToUtf16BE(allocator: *std.mem.Allocator, utf8: []const u8) ![]u16 {
var utf16LE = try std.unicode.utf8ToUtf16LeWithNull(allocator, utf8);
// Little Endian to Big Endian
var utf16BE = byteSwapArray(u16, &utf16LE);
return utf16BE;
}
pub fn utf16BEToUtf8(allocator: *std.mem.Allocator, utf16: []u16) ![]u8 {
// Copy the strong so can do byte swap in place on it.
var utf16BE = try allocator.alloc(u16, utf16.len);
defer allocator.free(utf16BE);
std.mem.copy(u16, utf16BE, utf16);
// Big Endian to Little Endian
var utf16LE = byteSwapArray(u16, &utf16BE);
var utf8 = try std.unicode.utf16leToUtf8AllocZ(allocator, utf16LE);
return utf8;
}
test "utf8 and utf16BE conversion" {
var utf8 = "1312";
var utf16BE = try utf8ToUtf16BE(testing.allocator, utf8);
defer testing.allocator.free(utf16BE);
var utf8Decoded = try utf16BEToUtf8(testing.allocator, utf16BE);
defer testing.allocator.free(utf8Decoded);
try testing.expectEqualStrings(utf8, utf8Decoded);
}

View file

@ -4,7 +4,7 @@ const QVariantType = @import("../types/QVariant.zig").QVariant;
const writeUInt = @import("./writeUInt.zig").writeUInt;
const writeQVariant = @import("./writeQVariant.zig").writeQVariant;
pub fn writeFrame(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(QVariantType)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void {
pub fn writeFrame(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(QVariantType)) !void {
var data = std.ArrayList(u8).init(allocator);
try writeQVariant(data.writer(), allocator, .{
.QVariantMap = map,

View file

@ -14,7 +14,7 @@ const writeQVariantHeader = @import("./writeQVariantHeader.zig").writeQVariantHe
const writeQVariantMap = @import("./writeQVariantMap.zig").writeQVariantMap;
const writeQStringList = @import("./writeQStringList.zig").writeQStringList;
pub fn writeQVariant(writer: anytype, allocator: *std.mem.Allocator, variant: QVariantType) !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));
switch (variant) {
.Byte => |out| {

View file

@ -3,8 +3,7 @@ const QVariantType = @import("../types/QVariant.zig").QVariant;
const writeUInt = @import("./writeUInt.zig").writeUInt;
const writeQVariant = @import("./writeQVariant.zig").writeQVariant;
const AllKnownErrors = (std.os.WriteError || error{OutOfMemory});
pub fn writeQVariantList(writer: anytype, allocator: *std.mem.Allocator, varList: []QVariantType) AllKnownErrors!void {
pub fn writeQVariantList(writer: anytype, allocator: *std.mem.Allocator, varList: []QVariantType) !void {
try writeUInt(writer, @intCast(u32, varList.len));
for (varList) |v| {
try writeQVariant(writer, allocator, v);

View file

@ -5,7 +5,7 @@ const writeUInt = @import("./writeUInt.zig").writeUInt;
const writeQVariant = @import("./writeQVariant.zig").writeQVariant;
pub fn writeQVariantMap(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(QVariantType)) (@TypeOf(writer).Error || std.os.WriteError || error{OutOfMemory})!void {
pub fn writeQVariantMap(writer: anytype, allocator: *std.mem.Allocator, map: std.StringHashMap(QVariantType)) !void {
var data = std.ArrayList(u8).init(allocator);
defer data.deinit();

View file

@ -1,13 +1,11 @@
const std = @import("std");
const writeInt = @import("./writeInt.zig").writeInt;
const unicode = @import("../utils/unicode.zig");
pub fn writeString(writer: anytype, allocator: *std.mem.Allocator, str: []const u8) !void {
var ut16Str = try allocator.alloc(u16, str.len);
defer allocator.free(ut16Str);
for (str) |character, index| {
ut16Str[index] = std.mem.nativeToBig(u16, @as(u16, character));
}
try writeInt(writer, @intCast(i32, ut16Str.len * 2));
try writer.writeAll(std.mem.sliceAsBytes(ut16Str));
pub fn writeString(writer: anytype, allocator: *std.mem.Allocator, str: []const u8) (error{InvalidUtf8} || error{OutOfMemory})!void {
var str_utf16BE = try unicode.utf8ToUtf16BE(allocator, str);
defer allocator.free(str_utf16BE);
try writeInt(writer, @intCast(i32, str_utf16BE.len));
try writer.writeAll(std.mem.sliceAsBytes(str_utf16BE));
}