mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Merge 946ed0db9e into 9082b004b6
This commit is contained in:
commit
4bc2c55a1a
5 changed files with 84 additions and 8 deletions
|
|
@ -1,3 +1,8 @@
|
|||
pub const asn1 = @import("codecs/asn1.zig");
|
||||
pub const base64 = @import("codecs/base64_hex_ct.zig").base64;
|
||||
pub const hex = @import("codecs/base64_hex_ct.zig").hex;
|
||||
|
||||
test {
|
||||
_ = @import("codecs/asn1.zig");
|
||||
_ = @import("codecs/base64_hex_ct.zig");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ pub const Tag = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn encode(self: Tag, writer: *std.Io.Writer) @TypeOf(writer).Error!void {
|
||||
pub fn encode(self: Tag, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||
var tag1 = FirstTag{
|
||||
.number = undefined,
|
||||
.constructed = self.constructed,
|
||||
|
|
@ -98,7 +98,7 @@ pub const Tag = struct {
|
|||
};
|
||||
|
||||
var buffer: [3]u8 = undefined;
|
||||
var writer2: std.Io.Writer = .init(&buffer);
|
||||
var writer2: std.Io.Writer = .fixed(&buffer);
|
||||
|
||||
switch (@intFromEnum(self.number)) {
|
||||
0...std.math.maxInt(u5) => |n| {
|
||||
|
|
@ -183,7 +183,7 @@ pub const Element = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub const DecodeError = error{ InvalidLength, EndOfStream };
|
||||
pub const DecodeError = error{ InvalidLength, EndOfStream, ReadFailed };
|
||||
|
||||
/// Safely decode a DER/BER/CER element at `index`:
|
||||
/// - Ensures length uses shortest form
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ test fromDot {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toDot(self: Oid, writer: anytype) @TypeOf(writer).Error!void {
|
||||
pub fn toDot(self: Oid, writer: anytype) std.Io.Writer.Error!void {
|
||||
const encoded = self.encoded;
|
||||
const first = @divTrunc(encoded[0], 40);
|
||||
const second = encoded[0] - first * 40;
|
||||
|
|
@ -81,7 +81,7 @@ test toDot {
|
|||
for (test_cases) |t| {
|
||||
var stream: std.Io.Writer = .fixed(&buf);
|
||||
try toDot(Oid{ .encoded = t.encoded }, &stream);
|
||||
try std.testing.expectEqualStrings(t.dot_notation, stream.written());
|
||||
try std.testing.expectEqualStrings(t.dot_notation, stream.buffered());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,18 +7,28 @@
|
|||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Io = std.Io;
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
|
||||
data: []u8,
|
||||
capacity: usize,
|
||||
allocator: Allocator,
|
||||
writer: Io.Writer,
|
||||
|
||||
const ArrayListReverse = @This();
|
||||
const Error = Allocator.Error;
|
||||
|
||||
pub fn init(allocator: Allocator) ArrayListReverse {
|
||||
return .{ .data = &.{}, .capacity = 0, .allocator = allocator };
|
||||
return .{
|
||||
.data = &.{},
|
||||
.capacity = 0,
|
||||
.allocator = allocator,
|
||||
.writer = .{
|
||||
.buffer = &.{},
|
||||
.vtable = &vtable,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *ArrayListReverse) void {
|
||||
|
|
@ -67,6 +77,67 @@ pub fn clearAndFree(self: *ArrayListReverse) void {
|
|||
self.capacity = 0;
|
||||
}
|
||||
|
||||
const vtable: Io.Writer.VTable = .{
|
||||
.drain = &drain,
|
||||
};
|
||||
|
||||
fn drain(w: *Io.Writer, data: []const []const u8, splat: usize) Io.Writer.Error!usize {
|
||||
const self: *ArrayListReverse = @fieldParentPtr("writer", w);
|
||||
|
||||
assert(w.buffered().len == 0);
|
||||
|
||||
if (data.len == 1 and splat == 1) {
|
||||
@branchHint(.likely);
|
||||
self.prependSlice(data[0]) catch return error.WriteFailed;
|
||||
return data[0].len;
|
||||
}
|
||||
|
||||
const count = Io.Writer.countSplat(data, splat);
|
||||
self.ensureCapacity(self.data.len + count) catch return error.WriteFailed;
|
||||
const end = self.data.ptr;
|
||||
const begin = end - count;
|
||||
var slice = begin[0..count];
|
||||
|
||||
for (data[0 .. data.len - 1]) |bytes| {
|
||||
@memcpy(slice[0..bytes.len], bytes);
|
||||
slice = slice[bytes.len..];
|
||||
}
|
||||
for (0..splat) |_| {
|
||||
const bytes = data[data.len - 1];
|
||||
@memcpy(slice[0..bytes.len], bytes);
|
||||
slice = slice[bytes.len..];
|
||||
}
|
||||
|
||||
self.data.ptr = begin;
|
||||
self.data.len += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
test drain {
|
||||
var b: ArrayListReverse = .init(std.testing.allocator);
|
||||
defer b.deinit();
|
||||
|
||||
var n = try b.writer.write(&.{ 1, 2, 3 });
|
||||
try std.testing.expectEqual(3, n);
|
||||
try std.testing.expectEqualSlices(u8, &.{ 1, 2, 3 }, b.data);
|
||||
|
||||
n = try b.writer.writeSplat(&.{
|
||||
&.{ 4, 5, 6 },
|
||||
&.{ 7, 8, 9 },
|
||||
}, 2);
|
||||
try std.testing.expectEqual(9, n);
|
||||
try std.testing.expectEqualSlices(
|
||||
u8,
|
||||
&.{
|
||||
4, 5, 6,
|
||||
7, 8, 9,
|
||||
7, 8, 9,
|
||||
1, 2, 3,
|
||||
},
|
||||
b.data,
|
||||
);
|
||||
}
|
||||
|
||||
/// The caller owns the returned memory.
|
||||
/// Capacity is cleared, making deinit() safe but unnecessary to call.
|
||||
pub fn toOwnedSlice(self: *ArrayListReverse) Error![]u8 {
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ pub fn tagBytes(self: *Encoder, tag_: Tag, bytes: []const u8) !void {
|
|||
}
|
||||
|
||||
/// Warning: This writer writes backwards. `fn print` will NOT work as expected.
|
||||
pub fn writer(self: *Encoder) ArrayListReverse.Writer {
|
||||
return self.buffer.writer();
|
||||
pub fn writer(self: *Encoder) *std.Io.Writer {
|
||||
return &self.buffer.writer;
|
||||
}
|
||||
|
||||
fn int(self: *Encoder, comptime T: type, value: T) !void {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue