@@ -4,7 +4,6 @@ const snappyz = @import("snappyz");
44
55const Allocator = std .mem .Allocator ;
66const math = std .math ;
7- const meta = std .meta ;
87
98const FrameError = error {
109 UnexpectedEof ,
@@ -30,7 +29,7 @@ const ChunkType = enum(u8) {
3029 pub const ParseError = error {InvalidValue };
3130
3231 pub fn fromByte (value : u8 ) ParseError ! ChunkType {
33- return meta . intToEnum (ChunkType , value ) catch ParseError .InvalidValue ;
32+ return std . enums . fromInt (ChunkType , value ) orelse ParseError .InvalidValue ;
3433 }
3534
3635 pub fn toByte (self : ChunkType ) u8 {
@@ -104,33 +103,33 @@ pub const FrameEncoder = struct {
104103
105104/// Encode all data into a fresh Snappy frame stored in an owned slice.
106105pub fn encode (allocator : Allocator , data : []const u8 ) ! []u8 {
107- var output = std .ArrayListUnmanaged ( u8 ). empty ;
108- errdefer output .deinit (allocator );
106+ var allocating = std .Io . Writer . Allocating . init ( allocator ) ;
107+ errdefer allocating .deinit ();
109108
110109 var encoder = FrameEncoder .init (allocator );
111110
112111 var index : usize = 0 ;
113112 while (index < data .len ) {
114113 const end_index = @min (index + recommended_chunk , data .len );
115114 const chunk_input = data [index .. end_index ];
116- try encoder .writeChunk (output .writer ( allocator ) , chunk_input );
115+ try encoder .writeChunk (& allocating .writer , chunk_input );
117116 index = end_index ;
118117 }
119118
120- try encoder .finish (output .writer ( allocator ) );
119+ try encoder .finish (& allocating .writer );
121120
122- return output .toOwnedSlice (allocator );
121+ return allocating .toOwnedSlice ();
123122}
124123
125124/// Stream input from `reader` into the frame writer without buffering the entire payload.
126- pub fn encodeToWriter (allocator : Allocator , reader : anytype , writer : anytype ) ! void {
125+ pub fn encodeToWriter (allocator : Allocator , reader : * std.Io.Reader , writer : * std.Io.Writer ) ! void {
127126 var encoder = FrameEncoder .init (allocator );
128127
129128 var chunk_input_buffer = try allocator .alloc (u8 , recommended_chunk );
130129 defer allocator .free (chunk_input_buffer );
131130
132131 while (true ) {
133- const read_len = try reader .read (chunk_input_buffer );
132+ const read_len = try reader .readSliceShort (chunk_input_buffer );
134133 if (read_len == 0 ) break ;
135134
136135 try encoder .writeChunk (writer , chunk_input_buffer [0.. read_len ]);
@@ -152,8 +151,8 @@ pub fn decode(allocator: Allocator, data: []const u8) ![]u8 {
152151}
153152
154153/// Decode framed input from `reader`, writing decompressed output into `writer`.
155- pub fn decodeFromReader (allocator : Allocator , reader : anytype , writer : anytype ) ! void {
156- var chunk_buf = std .ArrayListUnmanaged (u8 ).empty ;
154+ pub fn decodeFromReader (allocator : Allocator , reader : * std.Io.Reader , writer : * std.Io.Writer ) ! void {
155+ var chunk_buf : std .ArrayList (u8 ) = .empty ;
157156 defer chunk_buf .deinit (allocator );
158157
159158 var processed_any_chunk = false ;
@@ -222,8 +221,8 @@ fn decodeFramed(allocator: Allocator, data: []const u8) ![]u8 {
222221 var saw_data_chunk = false ;
223222 var saw_stream_identifier = false ;
224223
225- var output = std .ArrayListUnmanaged ( u8 ). empty ;
226- errdefer output .deinit (allocator );
224+ var allocating = std .Io . Writer . Allocating . init ( allocator ) ;
225+ errdefer allocating .deinit ();
227226
228227 while (cursor < data .len ) {
229228 if (data .len - cursor < 4 ) return FrameError .UnexpectedEof ;
@@ -251,13 +250,11 @@ fn decodeFramed(allocator: Allocator, data: []const u8) ![]u8 {
251250 saw_stream_identifier = true ;
252251 },
253252 .compressed = > {
254- const writer = output .writer (allocator );
255- try writeCompressedChunk (allocator , writer , chunk_data );
253+ try writeCompressedChunk (allocator , & allocating .writer , chunk_data );
256254 saw_data_chunk = true ;
257255 },
258256 .uncompressed = > {
259- const writer = output .writer (allocator );
260- try writeUncompressedChunk (writer , chunk_data );
257+ try writeUncompressedChunk (& allocating .writer , chunk_data );
261258 saw_data_chunk = true ;
262259 },
263260 }
@@ -276,7 +273,7 @@ fn decodeFramed(allocator: Allocator, data: []const u8) ![]u8 {
276273 if (! saw_data_chunk ) return FrameError .NotFramed ;
277274
278275 // Some producers may omit the identifier. Only enforce when data present with mismatched chunk.
279- return output .toOwnedSlice (allocator );
276+ return allocating .toOwnedSlice ();
280277}
281278
282279fn ensureStreamIdentifier (chunk_payload : []const u8 ) ! void {
@@ -286,15 +283,15 @@ fn ensureStreamIdentifier(chunk_payload: []const u8) !void {
286283 }
287284}
288285
289- fn writeUncompressedChunk (writer : anytype , chunk_payload : []const u8 ) ! void {
286+ fn writeUncompressedChunk (writer : * std.Io.Writer , chunk_payload : []const u8 ) ! void {
290287 if (chunk_payload .len < 4 ) return FrameError .UnexpectedEof ;
291288 const expected_checksum = readU32le (chunk_payload [0.. 4]);
292289 const raw_payload = chunk_payload [4.. ];
293290 try validateChecksum (raw_payload , expected_checksum );
294291 try writer .writeAll (raw_payload );
295292}
296293
297- fn writeCompressedChunk (allocator : Allocator , writer : anytype , chunk_payload : []const u8 ) ! void {
294+ fn writeCompressedChunk (allocator : Allocator , writer : * std.Io.Writer , chunk_payload : []const u8 ) ! void {
298295 if (chunk_payload .len < 4 ) return FrameError .UnexpectedEof ;
299296 const expected_checksum = readU32le (chunk_payload [0.. 4]);
300297 const compressed_payload = chunk_payload [4.. ];
@@ -304,7 +301,7 @@ fn writeCompressedChunk(allocator: Allocator, writer: anytype, chunk_payload: []
304301 try writer .writeAll (decoded );
305302}
306303
307- fn writeChunkHeader (writer : anytype , chunk_type : ChunkType , payload_len : usize ) ! void {
304+ fn writeChunkHeader (writer : * std.Io.Writer , chunk_type : ChunkType , payload_len : usize ) ! void {
308305 if (payload_len > max_chunk_len ) return FrameError .ChunkTooLarge ;
309306 const chunk_type_byte : u8 = chunk_type .toByte ();
310307 const byte0 : u8 = @intCast (payload_len & 0xff );
@@ -349,31 +346,24 @@ fn crc32c(data: []const u8) u32 {
349346 return std .hash .crc .Crc32Iscsi .hash (data );
350347}
351348
352- fn readExact (reader : anytype , buffer : []u8 ) ! void {
349+ fn readExact (reader : * std.Io.Reader , buffer : []u8 ) ! void {
353350 var index : usize = 0 ;
354351 while (index < buffer .len ) {
355- const read_len = try reader .read (buffer [index .. ]);
352+ const read_len = try reader .readSliceShort (buffer [index .. ]);
356353 if (read_len == 0 ) return FrameError .UnexpectedEof ;
357354 index += read_len ;
358355 }
359356}
360357
361- fn readByte (reader : anytype ) ! ? u8 {
358+ fn readByte (reader : * std.Io.Reader ) ! ? u8 {
362359 var byte : [1 ]u8 = undefined ;
363- const read_len = try reader .read (& byte );
360+ const read_len = try reader .readSliceShort (& byte );
364361 if (read_len == 0 ) return null ;
365362 return byte [0 ];
366363}
367364
368365fn loadFileAlloc (allocator : Allocator , path : []const u8 ) ! []u8 {
369- var file = try std .fs .cwd ().openFile (path , .{});
370- defer file .close ();
371-
372- const stat = try file .stat ();
373- const buf = try allocator .alloc (u8 , stat .size );
374- const read_len = try file .readAll (buf );
375- std .debug .assert (read_len == stat .size );
376- return buf ;
366+ return std .Io .Dir .cwd ().readFileAlloc (std .testing .io , path , allocator , .unlimited );
377367}
378368
379369const go_writer_golden_frame =
@@ -406,44 +396,45 @@ test "encodeToWriter matches encode" {
406396 const direct = try encode (allocator , sample );
407397 defer allocator .free (direct );
408398
409- var reader_stream = std .io . fixedBufferStream (sample );
410- var encoded_buffer = std .ArrayListUnmanaged ( u8 ). empty ;
411- defer encoded_buffer .deinit (allocator );
399+ var reader_stream : std.Io.Reader = . fixed (sample );
400+ var encoded_buffer = std .Io . Writer . Allocating . init ( allocator ) ;
401+ defer encoded_buffer .deinit ();
412402
413- try encodeToWriter (allocator , reader_stream . reader (), encoded_buffer .writer ( allocator ) );
403+ try encodeToWriter (allocator , & reader_stream , & encoded_buffer .writer );
414404
415- try std .testing .expectEqualSlices (u8 , direct , encoded_buffer .items );
405+ try std .testing .expectEqualSlices (u8 , direct , encoded_buffer .written () );
416406}
417407
418408test "FrameEncoder manual streaming API" {
419409 const allocator = std .testing .allocator ;
420410 const parts = [_ ][]const u8 { "frame-" , "encoder-" , "stream" };
421411
422412 var encoder = FrameEncoder .init (allocator );
423- var encoded = std .ArrayListUnmanaged ( u8 ). empty ;
424- defer encoded .deinit (allocator );
413+ var encoded = std .Io . Writer . Allocating . init ( allocator ) ;
414+ defer encoded .deinit ();
425415
426416 var i : usize = 0 ;
427417 while (i < parts .len ) : (i += 1 ) {
428- try encoder .writeChunk (encoded .writer ( allocator ) , parts [i ]);
418+ try encoder .writeChunk (& encoded .writer , parts [i ]);
429419 }
430420
431- try encoder .finish (encoded .writer ( allocator ) );
421+ try encoder .finish (& encoded .writer );
432422
433- var combined_builder = std .ArrayListUnmanaged (u8 ).empty ;
423+ var combined_builder : std .ArrayList (u8 ) = .empty ;
434424 defer combined_builder .deinit (allocator );
435425 for (parts ) | segment | {
436426 try combined_builder .appendSlice (allocator , segment );
437427 }
438428 const combined = try combined_builder .toOwnedSlice (allocator );
439429 defer allocator .free (combined );
440430
441- const decoded_manual = try decode (allocator , encoded .items );
431+ const encoded_bytes = encoded .written ();
432+ const decoded_manual = try decode (allocator , encoded_bytes );
442433 defer allocator .free (decoded_manual );
443434
444435 try std .testing .expectEqualSlices (u8 , combined , decoded_manual );
445436
446- try std .testing .expect (std .mem .startsWith (u8 , encoded . items , stream_identifier ));
437+ try std .testing .expect (std .mem .startsWith (u8 , encoded_bytes , stream_identifier ));
447438}
448439
449440test "decodeFromReader matches decode" {
@@ -453,13 +444,13 @@ test "decodeFromReader matches decode" {
453444 const encoded = try encode (allocator , sample );
454445 defer allocator .free (encoded );
455446
456- var reader_stream = std .io . fixedBufferStream (encoded );
457- var decoded_buffer = std .ArrayListUnmanaged ( u8 ). empty ;
458- defer decoded_buffer .deinit (allocator );
447+ var reader_stream : std.Io.Reader = . fixed (encoded );
448+ var decoded_buffer = std .Io . Writer . Allocating . init ( allocator ) ;
449+ defer decoded_buffer .deinit ();
459450
460- try decodeFromReader (allocator , reader_stream . reader (), decoded_buffer .writer ( allocator ) );
451+ try decodeFromReader (allocator , & reader_stream , & decoded_buffer .writer );
461452
462- try std .testing .expectEqualSlices (u8 , sample , decoded_buffer .items );
453+ try std .testing .expectEqualSlices (u8 , sample , decoded_buffer .written () );
463454}
464455
465456test "frame roundtrip samples" {
0 commit comments