ostify/src/trackinfo.zig

71 lines
2.0 KiB
Zig

const std = @import("std");
const mem = std.mem;
const Self = @This();
const InfoKey = enum {
Title,
Author,
Source,
OriginalComposers,
};
const source_original = "Dr. Robotnik's Ring Racers";
allocator: mem.Allocator,
id: []const u8,
title: ?[]const u8,
author: ?[]const u8,
source: ?[]const u8,
originalComposers: ?[]const u8,
is_original: bool,
pub fn parseLump(allocator: mem.Allocator, lump: []const u8) !Self {
// Get lines
var lines = mem.tokenize(u8, lump, "\n");
// Next line is the ID, we need that ASAP!
const id = mem.trim(u8, lines.next().?, " \r");
var info = Self{
.allocator = allocator,
.id = try allocator.dupe(u8, id),
.title = null,
.author = null,
.source = null,
.originalComposers = null,
.is_original = false,
};
// Read rest of lump and assign to fields in struct
while (lines.next()) |line| {
const sep = mem.indexOf(u8, line, "=");
if (sep) |sepIndex| {
const key = mem.trim(u8, line[0..sepIndex], " \r");
const val = mem.trim(u8, line[sepIndex + 1 ..], " \r");
const ownedVal = try allocator.dupe(u8, val);
const infoKey = std.meta.stringToEnum(InfoKey, key) orelse continue;
switch (infoKey) {
.Title => info.title = ownedVal,
.Author => info.author = ownedVal,
.Source => info.source = ownedVal,
.OriginalComposers => info.originalComposers = ownedVal,
}
}
}
// Check if it's an original work
if (info.source) |source| {
info.is_original = mem.eql(u8, source, source_original);
}
return info;
}
pub fn deinit(self: Self) void {
self.allocator.free(self.id);
if (self.title) |ptr| self.allocator.free(ptr);
if (self.author) |ptr| self.allocator.free(ptr);
if (self.source) |ptr| self.allocator.free(ptr);
if (self.title) |ptr| self.allocator.free(ptr);
if (self.originalComposers) |ptr| self.allocator.free(ptr);
}