···
21
21
buf.string(); // "over 9000!"
22
22
```
23
23
24
24
-
You can call `buf.writer()` to get an `std.io.Writer`.
24
24
+
You can access `&buf.interface` to get an `*std.io.Writer`.
25
25
26
26
You can use `writeU16Big`, `writeU32Big`, `writeU64Big` and `writeU16Little`, `writeU32Little`, `writeU64Little` to write integer values.
27
27
···
32
32
// created when we try to write more than static.len
33
33
dynamic: ?[]u8,
34
34
35
35
+
interface: std.Io.Writer,
36
36
+
35
37
pub fn init(allocator: Allocator, size: usize) !Buffer {
36
38
const static = try allocator.alloc(u8, size);
37
39
return .{
···
41
43
.buf = static,
42
44
.static = static,
43
45
.dynamic = null,
46
46
+
.interface = .{
47
47
+
.buffer = &.{},
48
48
+
.vtable = &.{
49
49
+
.drain = drain,
50
50
+
},
51
51
+
}
44
52
};
45
53
}
46
54
···
50
58
if (self.dynamic) |dyn| {
51
59
(self._da orelse allocator).free(dyn);
52
60
}
61
61
+
}
62
62
+
63
63
+
pub fn drain(io_w: *std.io.Writer, data: []const []const u8, splat: usize) error{WriteFailed}!usize {
64
64
+
_ = splat;
65
65
+
const self: *Buffer = @alignCast(@fieldParentPtr("interface", io_w));
66
66
+
self.write(data[0]) catch return error.WriteFailed;
67
67
+
return data[0].len;
53
68
}
54
69
55
70
pub fn reset(self: *Buffer) void {
···
217
232
@memcpy(c, self.buf[0..pos]);
218
233
return c;
219
234
}
220
220
-
221
221
-
pub fn writer(self: *Buffer) Writer {
222
222
-
return .init(self);
223
223
-
}
224
224
-
225
225
-
pub const Writer = struct {
226
226
-
w: *Buffer,
227
227
-
interface: std.io.Writer,
228
228
-
229
229
-
pub const Error = Allocator.Error;
230
230
-
231
231
-
fn init(w: *Buffer) Writer {
232
232
-
return .{
233
233
-
.w = w,
234
234
-
.interface = .{
235
235
-
.vtable = &.{
236
236
-
.drain = drain,
237
237
-
},
238
238
-
.buffer = &.{},
239
239
-
},
240
240
-
};
241
241
-
}
242
242
-
243
243
-
pub fn adaptToNewApi(self: Writer) Adapter {
244
244
-
return .{ .new_interface = self.interface };
245
245
-
}
246
246
-
247
247
-
pub fn drain(io_w: *std.io.Writer, data: []const []const u8, splat: usize) error{WriteFailed}!usize {
248
248
-
_ = splat;
249
249
-
const self: *Writer = @alignCast(@fieldParentPtr("interface", io_w));
250
250
-
self.w.write(data[0]) catch return error.WriteFailed;
251
251
-
return data[0].len;
252
252
-
}
253
253
-
254
254
-
// Legacy API
255
255
-
pub fn writeByte(self: Writer, b: u8) !void {
256
256
-
return self.w.writeByte(b);
257
257
-
}
258
258
-
pub fn writeByteNTimes(self: *Writer, b: u8, n: usize) !void {
259
259
-
return self.w.writeByteNTimes(b, n);
260
260
-
}
261
261
-
pub fn print(self: *Writer, comptime fmt: []const u8, args: anytype) !void {
262
262
-
return self.interface.print(fmt, args) catch return error.OutOfMemory;
263
263
-
}
264
264
-
pub fn writeAll(self: Writer, data: []const u8) !void {
265
265
-
return self.w.write(data);
266
266
-
}
267
267
-
268
268
-
pub const Adapter = struct {
269
269
-
err: ?Error = null,
270
270
-
new_interface: std.Io.Writer,
271
271
-
};
272
272
-
};
273
235
};
274
236
275
237
pub const View = struct {
···
488
450
}
489
451
490
452
test "fuzz" {
491
491
-
var control = std.ArrayList(u8).init(t.allocator);
492
492
-
defer control.deinit();
453
453
+
var control: std.ArrayList(u8) = .empty;
454
454
+
defer control.deinit(t.allocator);
493
455
494
456
var r = t.getRandom();
495
457
const random = r.random();
···
506
468
for (1..100) |_| {
507
469
const input = testString(aa, random);
508
470
try w.write(input);
509
509
-
try control.appendSlice(input);
471
471
+
try control.appendSlice(t.allocator, input);
510
472
try t.expectString(control.items, w.string());
511
473
}
512
474
w.reset();
···
519
481
var w = try Buffer.init(t.allocator, 10);
520
482
defer w.deinit();
521
483
522
522
-
try std.json.stringify(.{ .over = 9000, .spice = "must flow", .ok = true }, .{}, w.writer());
484
484
+
try std.json.Stringify.value(.{ .over = 9000, .spice = "must flow", .ok = true }, .{}, &w.interface);
523
485
try t.expectString("{\"over\":9000,\"spice\":\"must flow\",\"ok\":true}", w.string());
524
486
}
525
487