Skip to documentation
SLOP

tiny.quic.varint

Reference tiny.quic varint

Defined in tiny.quic.

API (8)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstiny.quicvarint
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallstest sourcelib.quic.src.varinttest: RFC 9000 section 16 accepts per...test sourcelib.quic.src.varint.test_RFC_9000_section_16_...1 varint known answerscursor.Readinitvarintreadvarintdecode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.quic.src.transportwriteIntegertest sourcelib.quic.src.varint.test_RFC_9000_section_16_...1 varint known answerscursor.Writeinitvarintwritevarintencode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.quic.src.frame.codecreadTypevarintwritevarintencodedLength
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsframedecodeprivate sourcelib.quic.src.frame.codecdecodeAckprivate sourcelib.quic.src.frame.codecdecodeConnectionCloseprivate sourcelib.quic.src.frame.codecdecodeCryptoprivate sourcelib.quic.src.frame.codecdecodeDatagram+12 morevarintread
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsframeencodeprivate sourcelib.quic.src.frame.codecencodeAckprivate sourcelib.quic.src.frame.codecencodeConnectionCloseprivate sourcelib.quic.src.frame.codecencodeNewConnectionIdprivate sourcelib.quic.src.frame.codecencodeOne+8 morevarintencodedLengthvarintwrite
Static calls · unresolved targets: 0 · external targets: 2.

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.

Complete caller list for varint.write

13 direct callers.

Audit

Definitions7
Public names7
Members2
Version26.7.0
Revisiondaab053ee433