tiny.quic.varint
Defined in tiny.quic.
API (8)
Actions
Public operations.
decode: Reads one varint from the front of a byte slice and returns its value with the number of bytes it took, so a caller holding a plain byte slice calls it without building a cursor first.encodeencodedLengthread: Reads one varint from a read cursor and returns its value with the number of bytes it took, so a codec takes the next varint out of a byte stream and leaves the cursor past it.write
Types and contracts
Public types and contracts.
Source
Source: lib/quic/src/root.zig:52
zig
pub const varint = @import("varint.zig");Source: lib/quic/src/varint.zig
zig
const std = @import("std");const cursor = @import("cursor.zig");pub const EncodeError = cursor.WriteError;pub const DecodeError = cursor.ReadError;pub const Decoded = struct { value: u62, length: u4,};pub fn encodedLength(value: u62) u4 { if (value <= 63) return 1; if (value <= 16_383) return 2; if (value <= 1_073_741_823) return 4; return 8;}pub fn write(value: u62, output: *cursor.Write) EncodeError!u4 { const length = encodedLength(value); switch (length) { 1 => try output.byte(@intCast(value)), 2 => try output.int(u16, @as(u16, @intCast(value)) | 0x4000), 4 => try output.int(u32, @as(u32, @intCast(value)) | 0x8000_0000), 8 => try output.int(u64, @as(u64, value) | 0xc000_0000_0000_0000), else => unreachable, } return length;}pub fn encode(value: u62, out: []u8) EncodeError!u4 { var output = cursor.Write.init(out); return write(value, &output);}/// Reads one varint from a read cursor and returns its value with the number of bytes it took, so a/// codec takes the next varint out of a byte stream and leaves the cursor past it. The width comes/// from the top two bits of the first byte. A value written in a wider form than it needs is/// accepted and decoded to the same value, which RFC 9000 section 16 permits. The frame codec/// rejects a non-minimal frame type. Too few bytes for the selected width give `Truncated`.pub fn read(input: *cursor.Read) DecodeError!Decoded { const first = try input.byte(); const length: u4 = @as(u4, 1) << @intCast(first >> 6); const tail = try input.take(@as(usize, length) - 1); var value: u64 = first & 0x3f; for (0..7) |index| { if (index >= tail.len) break; value = (value << 8) | tail[index]; } std.debug.assert(value <= std.math.maxInt(u62)); return .{ .value = @intCast(value), .length = length };}/// Reads one varint from the front of a byte slice and returns its value with the number of bytes/// it took, so a caller holding a plain byte slice calls it without building a cursor first. It/// wraps the cursor form, so it accepts the same non-minimal encodings RFC 9000 section 16 permits,/// and the frame codec keeps the minimality rule for frame type fields. Bytes after the varint are/// left alone, and too few bytes give `Truncated`.pub fn decode(bytes: []const u8) DecodeError!Decoded { var input = cursor.Read.init(bytes); return read(&input);}test "RFC 9000 section 16 and Appendix A.1 varint known answers" { const Vector = struct { bytes: []const u8, value: u62 }; const vectors = [_]Vector{ .{ .bytes = &.{ 0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c }, .value = 151_288_809_941_952_652, }, .{ .bytes = &.{ 0x9d, 0x7f, 0x3e, 0x7d }, .value = 494_878_333 }, .{ .bytes = &.{ 0x7b, 0xbd }, .value = 15_293 }, .{ .bytes = &.{0x25}, .value = 37 }, }; for (vectors) |vector| { const decoded = try decode(vector.bytes); try std.testing.expectEqual(vector.value, decoded.value); try std.testing.expectEqual(vector.bytes.len, decoded.length); var encoded: [8]u8 = undefined; const length = try encode(vector.value, &encoded); try std.testing.expectEqualSlices(u8, vector.bytes, encoded[0..length]); }}test "RFC 9000 section 16 accepts permitted non-minimal varints" { const decoded = try decode(&.{ 0x40, 0x25 }); try std.testing.expectEqual(@as(u62, 37), decoded.value); try std.testing.expectEqual(@as(u4, 2), decoded.length);}Complete caller list for varint.read
17 direct callers.
tiny.quic.frame.decode[function] atlib/quic/src/frame/codec.zig:187lib.quic.src.frame.codec.decodeAck[function] — private source atlib/quic/src/frame/codec.zig:75in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeConnectionClose[function] — private source atlib/quic/src/frame/codec.zig:164in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeCrypto[function] — private source atlib/quic/src/frame/codec.zig:105in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeDatagram[function] — private source atlib/quic/src/frame/codec.zig:179in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeNewConnectionId[function] — private source atlib/quic/src/frame/codec.zig:145in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeStream[function] — private source atlib/quic/src/frame/codec.zig:119in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeStreamData[function] — private source atlib/quic/src/frame/codec.zig:227in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeStreamLimit[function] — private source atlib/quic/src/frame/codec.zig:139in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.decodeToken[function] — private source atlib/quic/src/frame/codec.zig:113in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.readAckRange[function] — private source atlib/quic/src/frame/codec.zig:62in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.readType[function] — private source atlib/quic/src/frame/codec.zig:54in nearest public ownerlib.quic.src.frame.codeclib.quic.src.packet.header.decodeInitial[function] — private source atlib/quic/src/packet/header.zig:59in nearest public ownerlib.quic.src.packet.headerlib.quic.src.packet.header.decodeProtected[function] — private source atlib/quic/src/packet/header.zig:72in nearest public ownerlib.quic.src.packet.headertiny.quic.transport.decode[function] atlib/quic/src/transport.zig:195lib.quic.src.transport.readInteger[function] — private source atlib/quic/src/transport.zig:80in nearest public ownertiny.quic.transporttiny.quic.varint.decode[function] atlib/quic/src/varint.zig:59
Complete caller list for varint.write
13 direct callers.
tiny.quic.frame.encode[function] atlib/quic/src/frame/codec.zig:331lib.quic.src.frame.codec.encodeAck[function] — private source atlib/quic/src/frame/codec.zig:254in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.encodeConnectionClose[function] — private source atlib/quic/src/frame/codec.zig:316in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.encodeNewConnectionId[function] — private source atlib/quic/src/frame/codec.zig:302in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.encodeOne[function] — private source atlib/quic/src/frame/codec.zig:383in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.encodeStream[function] — private source atlib/quic/src/frame/codec.zig:278in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.encodeStreamData[function] — private source atlib/quic/src/frame/codec.zig:388in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.encodeStreamLimit[function] — private source atlib/quic/src/frame/codec.zig:292in nearest public ownerlib.quic.src.frame.codeclib.quic.src.frame.codec.writeAckRange[function] — private source atlib/quic/src/frame/codec.zig:240in nearest public ownerlib.quic.src.frame.codectiny.quic.packet.encodeLong[function] atlib/quic/src/packet/header.zig:139lib.quic.src.packet.header.writeProtected[function] — private source atlib/quic/src/packet/header.zig:128in nearest public ownerlib.quic.src.packet.headerlib.quic.src.transport.writeTuple[function] — private source atlib/quic/src/transport.zig:214in nearest public ownertiny.quic.transporttiny.quic.varint.encode[function] atlib/quic/src/varint.zig:31
Audit
| Definitions | 7 |
|---|---|
| Public names | 7 |
| Members | 2 |
| Version | 26.7.0 |
| Revision | daab053ee433 |