|
1 | | -const std = @import("std"); |
2 | 1 | const brotli = @import("brotli"); |
| 2 | +const std = @import("std"); |
| 3 | +const reader = @import("../byte_read.zig"); |
| 4 | +const mod = @import("../parser.zig"); |
| 5 | +const Head = @import("../table/head.zig"); |
| 6 | +const byte_writer = @import("../byte_writer.zig"); |
| 7 | +const Impl = @import("./impl.zig"); |
3 | 8 |
|
4 | | -test "brotli round-trip encode/decode" { |
5 | | - const allocator = std.testing.allocator; |
6 | | - const input = "hello, world! this is a test for brotli encoder/decoder."; |
| 9 | +const Allocator = std.mem.Allocator; |
7 | 10 |
|
8 | | - var encoder = try brotli.Encoder.init(allocator, .{}); |
9 | | - defer encoder.deinit(); |
10 | | - const compressed = try encoder.encode(input); |
| 11 | +const Parser = mod.Parser; |
| 12 | +const ByteWriter = byte_writer.ByteWriter; |
| 13 | + |
| 14 | +// https://www.w3.org/TR/WOFF2/ |
| 15 | +pub const Woff = struct { |
| 16 | + const Self = @This(); |
| 17 | + |
| 18 | + allocator: Allocator, |
| 19 | + parser: *Parser, |
| 20 | + compressor: *const fn (allocator: Allocator, data: []const u8) anyerror![]u8, |
| 21 | + |
| 22 | + pub fn init( |
| 23 | + allocator: Allocator, |
| 24 | + parser: *Parser, |
| 25 | + compressor: *const fn (allocator: Allocator, data: []const u8) anyerror![]u8, |
| 26 | + ) Impl { |
| 27 | + const self = allocator.create(Self) catch unreachable; |
| 28 | + self.* = Self{ |
| 29 | + .allocator = allocator, |
| 30 | + .parser = parser, |
| 31 | + .compressor = compressor, |
| 32 | + }; |
| 33 | + return Impl{ |
| 34 | + .ptr = self, |
| 35 | + .vtable = &.{ |
| 36 | + .as_woff = as_woff, |
| 37 | + }, |
| 38 | + }; |
| 39 | + } |
11 | 40 |
|
12 | | - var decoder = try brotli.Decoder.init(allocator, .{}); |
13 | | - defer decoder.deinit(); |
14 | | - const decompressed = try decoder.decode(compressed); |
| 41 | + fn as_woff(ptr: *anyopaque) ![]u8 { |
| 42 | + const self: *Self = @ptrCast(@alignCast(ptr)); |
| 43 | + defer self.allocator.destroy(self); |
| 44 | + var buffer = ByteWriter(u8).init(self.allocator); |
| 45 | + try buffer.write(u8, 1, .big); |
15 | 46 |
|
16 | | - try std.testing.expectEqualStrings(input, decompressed); |
| 47 | + return buffer.to_owned_slice(); |
| 48 | + } |
| 49 | +}; |
17 | 50 |
|
18 | | - allocator.free(compressed); |
19 | | - allocator.free(decompressed); |
| 51 | +pub fn ttf_to_woff_v2(allocator: Allocator, data: []u8, compressor: Impl.Compressor) ![]u8 { |
| 52 | + var parser = try Parser.init(allocator, data); |
| 53 | + defer parser.deinit(); |
| 54 | + try parser.parse(); |
| 55 | + var woff = Woff.init(allocator, &parser, compressor); |
| 56 | + return woff.as_woff(); |
| 57 | +} |
| 58 | + |
| 59 | +pub fn ttf_woff_v2_with_parser(allocator: Allocator, parser: *Parser, compressor: Impl.Compressor) ![]u8 { |
| 60 | + var woff = Woff.init(allocator, parser, compressor); |
| 61 | + return woff.as_woff(); |
| 62 | +} |
| 63 | + |
| 64 | +// brotli mock |
| 65 | +fn mock_compressor(allocator: Allocator, data: []const u8) anyerror![]u8 { |
| 66 | + var encoder = try brotli.Encoder.init(allocator, .{}); |
| 67 | + defer encoder.deinit(); |
| 68 | + const compressed = try encoder.encode(data); |
| 69 | + return compressed; |
20 | 70 | } |
0 commit comments