138 lines
4.5 KiB
Zig
138 lines
4.5 KiB
Zig
const std = @import("std");
|
|
const p2 = @import("p2");
|
|
|
|
const constants = @import("constants.zig");
|
|
const PackedFileEntry = @This();
|
|
|
|
fileOffset: u64,
|
|
fileLen: u64,
|
|
|
|
fileNameLen: u32,
|
|
|
|
typeLen: u32,
|
|
|
|
fileName: [128]u8 = std.mem.zeroes([128]u8), // 128 bytes, zero-init because zeros are written to file for padding
|
|
typeName: [32]u8 = std.mem.zeroes([32]u8), // 32 bytes, zero-init because zeros are written to file for padding
|
|
//
|
|
pub fn init(typeName: []const u8, fileName: []const u8, fileOffset: u64, fileLen: u64) !@This() {
|
|
var self = @This(){
|
|
.fileLen = fileLen,
|
|
.fileOffset = fileOffset,
|
|
|
|
.fileNameLen = @intCast(fileName.len),
|
|
|
|
.typeLen = @intCast(typeName.len),
|
|
};
|
|
|
|
_ = try std.fmt.bufPrint(&self.fileName, "{s}", .{fileName});
|
|
_ = try std.fmt.bufPrint(&self.typeName, "{s}", .{typeName});
|
|
|
|
return self;
|
|
}
|
|
|
|
// todo make this a comptime, when i land and I am able to
|
|
// find out how comptime allocator interface looks.
|
|
pub fn calculateHeaderLen() usize {
|
|
// TODO
|
|
return 184;
|
|
}
|
|
|
|
pub fn loadFromReader(self: *@This(), reader: *std.Io.Reader) !void {
|
|
var bytesRead: usize = 0;
|
|
bytesRead += try reader.readSliceShort(p2.u64_to_slice(&self.fileOffset));
|
|
bytesRead += try reader.readSliceShort(p2.u64_to_slice(&self.fileLen));
|
|
bytesRead += try reader.readSliceShort(p2.u32_to_slice(&self.fileNameLen));
|
|
bytesRead += try reader.readSliceShort(p2.u32_to_slice(&self.typeLen));
|
|
|
|
bytesRead += try reader.readSliceShort(&self.fileName);
|
|
bytesRead += try reader.readSliceShort(&self.typeName);
|
|
|
|
std.debug.assert(bytesRead == calculateHeaderLen());
|
|
|
|
std.debug.print("header deserialized {s} type: {s} fileOffset:{d} \n", .{ self.getFileName(), self.getTypeName(), self.fileOffset });
|
|
}
|
|
|
|
// returns bytes written, not a true serialize function,
|
|
// writes out it's contents as it's meant to be read back to the writer.
|
|
pub fn writeHeader(self: @This(), writer: *std.Io.Writer, elementsCount: u32) !usize {
|
|
_ = elementsCount;
|
|
var bytesWritten: usize = 0;
|
|
|
|
bytesWritten += try writer.write(&@as([8]u8, @bitCast(self.fileOffset)));
|
|
bytesWritten += try writer.write(&@as([8]u8, @bitCast(self.fileLen)));
|
|
|
|
bytesWritten += try writer.write(&@as([4]u8, @bitCast(self.fileNameLen)));
|
|
bytesWritten += try writer.write(&@as([4]u8, @bitCast(self.typeLen)));
|
|
|
|
bytesWritten += try writer.write(&self.fileName);
|
|
bytesWritten += try writer.write(&self.typeName);
|
|
|
|
std.debug.assert(bytesWritten % 8 == 0);
|
|
|
|
std.debug.print("{s} serialized {d} bytes\n", .{ self.getFileName(), bytesWritten });
|
|
|
|
return bytesWritten;
|
|
}
|
|
|
|
pub fn getTypeName(self: *const @This()) []const u8 {
|
|
var slice: []const u8 = undefined;
|
|
|
|
slice.ptr = @ptrCast(&self.typeName);
|
|
slice.len = self.typeLen;
|
|
|
|
return slice;
|
|
}
|
|
|
|
pub fn getFileName(self: *const @This()) []const u8 {
|
|
var slice: []const u8 = undefined;
|
|
|
|
slice.ptr = @ptrCast(&self.fileName);
|
|
slice.len = self.fileNameLen;
|
|
|
|
return slice;
|
|
}
|
|
|
|
pub const ReaderIterator = struct {
|
|
totalCount: u32,
|
|
readCount: u32 = 0,
|
|
bytesRead: u64,
|
|
finished: bool = false,
|
|
|
|
// this iterator becomes invalidated if anythign else modifies
|
|
// the iterator is finished
|
|
pub fn init(reader: *std.Io.Reader) !@This() {
|
|
var bytesRead: usize = 0;
|
|
|
|
// read and verify magic
|
|
var magic: [4]u8 align(4) = undefined;
|
|
try p2.assert(try reader.readSliceShort(&magic) == 4);
|
|
try p2.assert(p2.arrayTo_u32(magic) == constants.PackerMagic);
|
|
bytesRead += 4;
|
|
|
|
// read the number of header entries
|
|
var entriesCount_read: [4]u8 align(4) = undefined;
|
|
try p2.assert(try reader.readSliceShort(&entriesCount_read) == 4);
|
|
const entriesCount = p2.arrayTo_u32(entriesCount_read);
|
|
std.debug.print("entriesCount = {d}\n", .{entriesCount});
|
|
bytesRead += 4;
|
|
|
|
return .{
|
|
.bytesRead = bytesRead,
|
|
.totalCount = entriesCount,
|
|
};
|
|
}
|
|
|
|
pub fn next(self: *@This(), reader: *std.Io.Reader) !?PackedFileEntry {
|
|
std.debug.print("readCount = {d}\n", .{self.readCount});
|
|
if (self.readCount == self.totalCount)
|
|
return null;
|
|
|
|
var newEntry: PackedFileEntry = undefined;
|
|
try newEntry.loadFromReader(reader);
|
|
self.bytesRead += PackedFileEntry.calculateHeaderLen();
|
|
self.readCount += 1;
|
|
|
|
return newEntry;
|
|
}
|
|
};
|