diff --git a/src/main.zig b/src/main.zig index 8045149..0e5d294 100644 --- a/src/main.zig +++ b/src/main.zig @@ -14,7 +14,7 @@ pub const CsvToken = union(CsvTokenType) { pub const CsvError = error{ ShortBuffer, MisplacedQuote, NoSeparatorAfterField }; pub const CsvConfig = struct { - colSeparator: u8 = ',', rowSeparator: u8 = '\n', initialBufferSize: usize = 1024 + colSeparator: u8 = ',', rowSeparator: u8 = '\n' }; fn CsvReader(comptime Reader: type) type { @@ -163,25 +163,17 @@ pub fn CsvTokenizer(comptime Reader: type) type { terminalChars: [3]u8 = undefined, reader: CsvReader(Reader), - allocator: *Allocator, status: Status = .Initial, - pub fn init(reader: Reader, allocator: *Allocator, config: CsvConfig) !Self { - var buffer = try allocator.alloc(u8, config.initialBufferSize); - + pub fn init(reader: Reader, buffer: []u8, config: CsvConfig) !Self { return Self{ .config = config, .terminalChars = [_]u8{ config.colSeparator, config.rowSeparator, '"' }, .reader = CsvReader(Reader).init(reader, buffer), - .allocator = allocator, }; } - pub fn deinit(self: Self) void { - self.allocator.free(self.reader.buffer); - } - pub fn next(self: *Self) !?CsvToken { while (true) { // print("STATUS: {}\n", .{self.status}); diff --git a/test/csv_tokenizer.zig b/test/csv_tokenizer.zig index ed0ad23..b5b8e31 100644 --- a/test/csv_tokenizer.zig +++ b/test/csv_tokenizer.zig @@ -5,9 +5,11 @@ const testing = std.testing; const expect = testing.expect; usingnamespace @import("csv"); -fn getTokenizer(file: std.fs.File, config: CsvConfig) !CsvTokenizer(std.fs.File.Reader) { +var default_buffer = [_]u8{0} ** 1024; + +fn getTokenizer(file: std.fs.File, buffer: []u8, config: CsvConfig) !CsvTokenizer(std.fs.File.Reader) { const reader = file.reader(); - const csv = try CsvTokenizer(std.fs.File.Reader).init(reader, testing.allocator, config); + const csv = try CsvTokenizer(std.fs.File.Reader).init(reader, buffer, config); return csv; } @@ -33,15 +35,14 @@ fn expectToken(comptime expected: CsvToken, maybeActual: ?CsvToken) !void { test "Create iterator for file reader" { const file = try std.fs.cwd().openFile("test/resources/test-1.csv", .{}); defer file.close(); - const csv = try getTokenizer(file, .{}); - defer csv.deinit(); + + const csv = try getTokenizer(file, &default_buffer, .{}); } test "Read single simple record from file" { const file = try std.fs.cwd().openFile("test/resources/test-1.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, .{}); - defer csv.deinit(); + const csv = &try getTokenizer(file, &default_buffer, .{}); try expectToken(CsvToken{ .field = "1" }, try csv.next()); try expectToken(CsvToken{ .field = "abc" }, try csv.next()); @@ -53,8 +54,7 @@ test "Read single simple record from file" { test "Read multiple simple records from file" { const file = try std.fs.cwd().openFile("test/resources/test-2.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, .{}); - defer csv.deinit(); + const csv = &try getTokenizer(file, &default_buffer, .{}); try expectToken(CsvToken{ .field = "1" }, try csv.next()); try expectToken(CsvToken{ .field = "abc" }, try csv.next()); @@ -70,8 +70,7 @@ test "Read multiple simple records from file" { test "Read quoted fields" { const file = try std.fs.cwd().openFile("test/resources/test-4.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, .{}); - defer csv.deinit(); + const csv = &try getTokenizer(file, &default_buffer, .{}); try expectToken(CsvToken{ .field = "1" }, try csv.next()); try expectToken(CsvToken{ .field = "def ghc" }, try csv.next()); @@ -87,8 +86,7 @@ test "Read quoted fields" { test "Second read is necessary to obtain field" { const file = try std.fs.cwd().openFile("test/resources/test-read-required-for-field.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, CsvConfig{ .initialBufferSize = 6 }); - defer csv.deinit(); + const csv = &try getTokenizer(file, default_buffer[0..6], .{}); try expectToken(CsvToken{ .field = "12345" }, try csv.next()); try expectToken(CsvToken{ .field = "67890" }, try csv.next()); @@ -100,8 +98,7 @@ test "Second read is necessary to obtain field" { test "File is empty" { const file = try std.fs.cwd().openFile("test/resources/test-empty.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, .{}); - defer csv.deinit(); + const csv = &try getTokenizer(file, &default_buffer, .{}); expect((try csv.next()) == null); } @@ -109,8 +106,7 @@ test "File is empty" { test "Field is longer than buffer" { const file = try std.fs.cwd().openFile("test/resources/test-error-short-buffer.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, CsvConfig{ .initialBufferSize = 9 }); - defer csv.deinit(); + const csv = &try getTokenizer(file, default_buffer[0..9], .{}); const field1 = csv.next(); if (field1) { @@ -123,8 +119,7 @@ test "Field is longer than buffer" { test "Quoted field is longer than buffer" { const file = try std.fs.cwd().openFile("test/resources/test-error-short-buffer-quoted.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, CsvConfig{ .initialBufferSize = 10 }); - defer csv.deinit(); + const csv = &try getTokenizer(file, default_buffer[0..10], .{}); const field1 = csv.next(); if (field1) { @@ -137,8 +132,7 @@ test "Quoted field is longer than buffer" { test "Quoted field with double quotes is longer than buffer" { const file = try std.fs.cwd().openFile("test/resources/test-error-short-buffer-quoted-with-double.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, CsvConfig{ .initialBufferSize = 11 }); - defer csv.deinit(); + const csv = &try getTokenizer(file, default_buffer[0..11], .{}); const field1 = csv.next(); if (field1) { @@ -151,8 +145,7 @@ test "Quoted field with double quotes is longer than buffer" { test "Quoted field with double quotes can be read on retry" { const file = try std.fs.cwd().openFile("test/resources/test-error-short-buffer-quoted-with-double.csv", .{}); defer file.close(); - const csv = &try getTokenizer(file, CsvConfig{ .initialBufferSize = 14 }); - defer csv.deinit(); + const csv = &try getTokenizer(file, default_buffer[0..14], .{}); try expectToken(CsvToken{ .field = "1234567890\"\"" }, try csv.next()); try expectToken(CsvToken{ .row_end = {} }, try csv.next());