Skip to documentation
SLOP

alloc_phase.input

Reference alloc_phase input

Internal implementation documentation

Defined in alloc_phase.

Package overview

API (5)

Actions

Public operations.

Types and contracts

Public types and contracts.

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

Source

Source: lib/alloc/phase/src/input/one.zig:46

zig
/// Packed boolean structure that enables specific input capabilities on an/// owner at compile time. All four fields default to `false`:////// * `reader`: Enables stream acquisition through `read`.////// * `file`: Enables filesystem acquisition through `readFile` and/// `readFileWindow`./// * `preflight`: Enables size admission checks through `preflight`./// * `map_file_too_big`: Maps `error.FileTooBig` from an underlying `readFile`/// call into a capacity rejection instead of propagating the raw I/O error.////// Because an owner must support at least one input mechanism, specification/// validation requires either `reader` or `file` to be enabled. Mapping/// file-size errors requires filesystem support, so `map_file_too_big` can be/// enabled only when `file` is also set to `true`. Individual acquisition/// methods verify their corresponding flags at compile time and raise a compile/// error when invoked without the required capability enabled.pub const Acquisition = packed struct {    reader: bool = false,    file: bool = false,    preflight: bool = false,    map_file_too_big: bool = false,};

Source: lib/alloc/phase/src/input/one.zig:27

zig
/// Error set returned when capacity derivation fails.////// Members:////// * `CapacityOverflow`: Adding one lookahead byte to the configured byte limit/// overflowed the range of `usize`.pub const DeriveError = error{CapacityOverflow};

Source: lib/alloc/phase/src/input/one.zig:68

zig
/// Defines the policy applied when an input exceeds the configured capacity/// limit.////// Tags:////// * `terminal`: Permanently seals the owner upon capacity rejection. Any/// subsequent acquisition attempt returns the capacity error immediately/// without performing I/O or incrementing rejection counters./// * `recoverable`: Preserves owner availability across rejections. Oversized/// inputs increment the rejection counter but leave the underlying storage free/// for subsequent attempts.////// Recovery designates the ability to reuse the allocated storage for later/// inputs. It does not provide source-position rollback, record framing, or/// automatic input drainage.pub const Overload = enum {    terminal,    recoverable,};

Source: lib/alloc/phase/src/input/one.zig:158

zig
/// Constructs an allocator-backed owner type for a single reusable input buffer/// based on a static specification structure.////// The `Spec` type parameter must satisfy several structural requirements:////// * `Limits`: Structure defining input limits. It must contain the field/// designated by `limit_field` typed as `usize`./// * `Capacity`: Structure defining storage requirements. It must expose a/// `derive(limits: Limits) DeriveError!Capacity` function, the field named by/// `limit_field` typed as `usize`, and `storage_bytes` typed as `usize`./// * `DeriveError`: Error set returned by `Capacity.derive`./// * `Exhaustion`: Error set returned when storage cannot admit an input./// * `Status`: Reporting structure returned by `status`. It must be a struct/// containing exactly seven fields for recoverable owners or eight fields for/// terminal owners: `phase: alloc_phase.capacity.Phase`, `in_use: bool`,/// `storage_bytes: usize`, the mapped limit, loaded, and high-water fields/// typed as `usize`, the mapped rejection field typed as `u64`, and/// conditionally `terminal: bool` when `overload` is `terminal`./// * `acquisition`: An instance of `Acquisition` specifying enabled I/O/// capabilities./// * `overload`: An instance of `Overload` setting either `.terminal` or/// `.recoverable` behavior./// * Field mappings: `limit_field`, `loaded_field`, `high_water_field`, and/// `rejected_field` specify field names on `Capacity` or `Status`. Callers must/// supply distinct names for these fields. Compile-time validation verifies/// field presence and total field counts, but this validation does not prove/// that mapped field names are mutually distinct./// * Error instances: `in_use_error` and `capacity_error` must both have type/// `Spec.Exhaustion`./// * `claim`: A static `alloc_phase.capacity.Declaration` metadata descriptor.////// The owner asserts that `storage_bytes` strictly exceeds the configured byte/// limit. While standard `deriveCapacity` derivation provides an exact `limit +/// 1` layout, custom `Capacity.derive` implementations may describe larger/// storage: derivation computes a `Capacity` value, while `init` allocates.////// A successful read operation returns a borrowed `[]const u8` slice pointing/// directly into the owned buffer and marks the owner as in use, including when/// the input is empty. Borrowers must consume or copy these bytes elsewhere/// before calling `release`. Slices must not be accessed after releasing the/// owner.////// A struct copy shares allocated storage but duplicates internal bookkeeping./// Copies are not independent owners: transferring exclusive ownership requires/// callers to stop using the original. Callers must serialize operations and/// ensure cleanup occurs exactly once.////// The owner is not thread-safe and performs no internal synchronization./// Callers accessing an owner across threads must provide external mutual/// exclusion.////// Lifecycle checks across initialization, steady operation, and teardown are/// enforced through debug assertions rather than explicit always-executed phase/// panics.pub fn OneRegion(comptime Spec: type) type {    comptime requireSpec(Spec);    return struct {        phase: alloc_phase.capacity.Phase,        capacity: Spec.Capacity,        bytes: []u8,        in_use: bool = false,        terminal: bool = false,        loaded_bytes: usize = 0,        high_water_bytes: usize = 0,        rejected_count: u64 = 0,        const Self = @This();        /// Result structure returned by `readFileWindow` representing a bounded        /// slice of a file read at a positional offset.        ///        /// Fields:        ///        /// * `bytes`: Borrowed const byte slice containing admitted data. Its        /// length is at most the requested window size.        /// * `complete`: Boolean flag set to `true` when `read_bytes <=        /// window_bytes`.        ///        /// The `complete` flag describes only this positional read and does not        /// make an immutable snapshot against concurrent modification during or        /// after it.        pub const FileWindow = struct {            bytes: []const u8,            complete: bool,        };        /// Type alias for `Spec.Limits`. Defines the input limit constraints        /// supplied by the caller.        pub const Limits: type = Spec.Limits;        /// Type alias for `Spec.Capacity`. Holds derived storage dimensions,        /// including the mandatory `storage_bytes` field.        pub const Capacity: type = Spec.Capacity;        /// Type alias for `Spec.Exhaustion`. Represents the error set returned        /// when input operations encounter a busy buffer or exceed configured        /// capacity.        pub const Exhaustion: type = Spec.Exhaustion;        /// Error set representing failures that can occur during        /// initialization. Combines allocator allocation errors with        /// `Spec.DeriveError`.        pub const InitError = std.mem.Allocator.Error || Spec.DeriveError;        /// Static capacity declaration describing the memory allocation        /// semantics of the generated owner.        ///        /// The declaration retains the complete `Spec.claim.source` envelope        /// while establishing fresh bindings for the generated owner:        ///        /// * `owner`: Binds the generated owner type `Self`.        /// * `source`: Binds the originating `Spec` configuration type.        /// * `seal`: Binds the `activate` method selector under the        /// `checked_semantic_fact` class with `checker` authority.        /// * `teardown`: Binds the `deinit` method selector under the        /// `checked_semantic_fact` class with `checker` authority.        ///        /// The bindings defined on `Spec.claim.bindings` are not reused.        /// Assigning premise labels to these new bindings does not prove their        /// truth. Local specification checks verify only that `claim` has type        /// `alloc_phase.capacity.Declaration`. Separate structural and        /// declaration checking verifies lifecycle declaration shape, but that        /// check does not prove whole-program allocation freedom.        pub const claim: alloc_phase.capacity.Declaration = .{            .source = Spec.claim.source,            .bindings = .{                .owner = Self,                .source = Spec,                .seal = .{                    .family = alloc_phase.capacity.selector(Self.activate),                    .premise = .{                        .class = .checked_semantic_fact,                        .authority = .checker,                    },                },                .teardown = .{                    .family = alloc_phase.capacity.selector(Self.deinit),                    .premise = .{                        .class = .checked_semantic_fact,                        .authority = .checker,                    },                },            },        };        /// Initializes a new input region by deriving capacity and allocating        /// the backing byte slice.        ///        /// The function derives capacity by evaluating        /// `Capacity.derive(limits)`. When derivation succeeds, it allocates        /// `capacity.storage_bytes` through the provided allocator. The        /// initialized owner enters the `.initialization` phase and retains the        /// allocated slice. The allocator handle itself is not stored on the        /// instance, so callers must provide the same allocator during        /// deinitialization.        ///        /// Initialization fails with `Spec.DeriveError` if capacity derivation        /// fails, or with `error.OutOfMemory` if memory allocation fails.        /// Before returning, debug assertions verify that the allocated slice        /// length equals `storage_bytes` and strictly exceeds the configured        /// byte limit.        pub fn init(allocator: std.mem.Allocator, limits: Limits) InitError!Self {            const capacity = try Capacity.derive(limits);            const bytes = try allocator.alloc(u8, capacity.storage_bytes);            const storage = Self{                .phase = .initialization,                .capacity = capacity,                .bytes = bytes,            };            storage.assertRegion();            return storage;        }        /// Transitions the owner from the initialization phase into steady        /// operation.        ///        /// Callers must activate the owner before performing input operations.        /// The function verifies through debug assertions that the owner        /// resides in the `.initialization` phase and that the backing buffer        /// satisfies region invariants. Once activated, `phase` transitions to        /// `.steady`, permitting acquisition calls.        pub fn activate(self: *Self) void {            std.debug.assert(self.phase == .initialization);            self.assertRegion();            self.phase = .steady;        }        /// Performs a size admission check for an expected input length without        /// executing I/O or modifying buffer contents.        ///        /// This method requires `Spec.acquisition.preflight` to be enabled at        /// compile time. Before evaluating the size, it verifies that the owner        /// is available in steady operation. If an operation is currently        /// active, it returns `Spec.in_use_error`. If the owner was previously        /// sealed in a terminal state, it returns `Spec.capacity_error`.        ///        /// The proposed length `input_bytes` is cast to `usize`. If the value        /// overflows `usize` or exceeds the configured byte limit, the method        /// invokes internal rejection, incrementing the saturating rejection        /// counter and applying the configured overload policy before returning        /// `Spec.capacity_error`.        ///        /// A successful preflight check confirms only that the proposed size        /// fits within the configured limit. It does not reserve storage, lock        /// the buffer, or establish an atomic guarantee between checking a size        /// and executing a later read.        pub fn preflight(self: *Self, input_bytes: u64) Exhaustion!void {            comptime requireAcquisition(Spec.acquisition.preflight, "preflight");            try self.requireAvailable();            const bounded = std.math.cast(usize, input_bytes) orelse                return self.reject();            if (bounded > self.limitBytes()) return self.reject();        }        /// Reads data from a stream reader into the owned buffer and admits the        /// resulting slice if its length falls within the configured limit.        ///        /// This method requires `Spec.acquisition.reader` to be enabled at        /// compile time. It requires the owner to be available in steady        /// operation, returning `Spec.in_use_error` if an active borrow exists        /// or `Spec.capacity_error` if the owner is terminal.        ///        /// The method invokes `reader.readSliceShort` over the allocated        /// storage slice. If reading from the underlying stream returns a        /// `ShortError` such as `ReadFailed`, that error propagates directly to        /// the caller. A read failure can occur after writing bytes into the        /// buffer and consuming bytes from the stream, without establishing a        /// borrow or recording a rejection. The method promises neither buffer        /// rollback nor stream rewind nor record framing.        ///        /// When reading completes without stream error, the read byte count is        /// evaluated:        ///        /// * If the count is at most the configured limit, the slice        /// `self.bytes[0..input_bytes]` is admitted. The owner records the        /// loaded length, updates the high-water mark, sets `in_use` to `true`,        /// and returns the borrowed slice.        /// * If the count exceeds the configured limit, the method rejects the        /// input. It increments the rejection counter, transitions to terminal        /// if configured, and returns `Spec.capacity_error`.        ///        /// When using helper-based capacity derivation through        /// `deriveCapacity`, an oversized input fills the `limit + 1` storage        /// bytes and triggers a capacity rejection after reading. This consumes        /// `limit + 1` bytes from the stream without draining trailing input.        /// Because reader implementations may buffer additional data,        /// subsequent reads cannot assume framing alignment with a subsequent        /// record.        pub fn read(            self: *Self,            reader: *std.Io.Reader,        ) (Exhaustion || std.Io.Reader.ShortError)![]const u8 {            comptime requireAcquisition(Spec.acquisition.reader, "reader");            try self.requireAvailable();            const input_bytes = try reader.readSliceShort(self.bytes);            return try self.admit(input_bytes);        }        /// Reads a file from a directory into the bounded buffer and admits the        /// resulting slice if the read length does not exceed the configured        /// limit.        ///        /// This method requires `Spec.acquisition.file` to be enabled at        /// compile time. It checks that the owner is available in steady        /// operation before opening the file.        ///        /// Reading is executed through `dir.readFile` into the allocated buffer        /// slice. Under the pinned standard library implementation, an ordinary        /// oversized file fills the buffer prefix before admission rejects the        /// input. Opening errors propagate directly, while a read error can        /// occur after partial buffer writes and no borrow is admitted.        ///        /// Handling of `error.FileTooBig` depends on compile-time        /// configuration:        ///        /// * When `Spec.acquisition.map_file_too_big` is `true`,        /// `error.FileTooBig` is converted into a capacity rejection. This        /// increments the rejection counter, transitions to terminal if        /// configured, and returns `Spec.capacity_error`.        /// * When `Spec.acquisition.map_file_too_big` is `false`,        /// `error.FileTooBig` propagates directly to the caller without        /// incrementing the rejection counter or modifying terminal state.        ///        /// All other filesystem I/O errors propagate directly to the caller        /// without a capacity rejection or terminal transition under either        /// setting. On success, the method returns a borrowed slice of the        /// admitted bytes and marks the owner as in use.        pub fn readFile(            self: *Self,            dir: std.Io.Dir,            io: std.Io,            file_path: []const u8,        ) ![]const u8 {            comptime requireAcquisition(Spec.acquisition.file, "file");            try self.requireAvailable();            const file = if (comptime Spec.acquisition.map_file_too_big)                dir.readFile(io, file_path, self.bytes) catch |err| switch (err) {                    error.FileTooBig => return self.reject(),                    else => return err,                }            else                try dir.readFile(io, file_path, self.bytes);            return try self.admit(file.len);        }        /// Reads a bounded positional window from a file at a specified offset        /// without treating trailing bytes as a capacity rejection.        ///        /// This method requires `Spec.acquisition.file` to be enabled at        /// compile time. Callers must supply a window size satisfying `0 <        /// window_bytes <= limit`, which debug assertions verify. The owner        /// must be available in steady operation before opening the target        /// file.        ///        /// The method opens the file and reads up to `window_bytes + 1` bytes        /// at the specified offset using positional I/O into `self.bytes[0 ..        /// window_bytes + 1]`. Any filesystem I/O error during open or read        /// propagates directly to the caller without a capacity rejection or        /// borrow, though the buffer may be partially written.        ///        /// The read byte count determines completion and admission:        ///        /// * If the number of read bytes is less than or equal to        /// `window_bytes`, `complete` is set to `true`.        /// * If reading produces `window_bytes + 1` bytes, additional data        /// exists beyond the window, setting `complete` to `false`. This        /// condition does not trigger a capacity rejection or modify terminal        /// status, even on terminal owners.        ///        /// The method admits `@min(read_bytes, window_bytes)`, which marks the        /// owner as in use and returns a borrowed slice. An immediate EOF        /// returning zero bytes still establishes an admitted zero-byte borrow.        /// The `complete` flag describes only this positional read and is not        /// an instantaneous snapshot against concurrent modifications.        pub fn readFileWindow(            self: *Self,            dir: std.Io.Dir,            io: std.Io,            file_path: []const u8,            offset: u64,            window_bytes: usize,        ) !FileWindow {            comptime requireAcquisition(Spec.acquisition.file, "file");            try self.requireAvailable();            std.debug.assert(window_bytes > 0);            std.debug.assert(window_bytes <= self.limitBytes());            var file = try dir.openFile(io, file_path, .{});            defer file.close(io);            const read_bytes = try file.readPositionalAll(                io,                self.bytes[0 .. window_bytes + 1],                offset,            );            const complete = read_bytes <= window_bytes;            const admitted = try self.admit(@min(read_bytes, window_bytes));            return .{ .bytes = admitted, .complete = complete };        }        /// Releases an active borrow, allowing the internal buffer to be reused        /// by future input operations.        ///        /// Callers must call this method only when the owner is in the        /// `.steady` phase, holds an active borrow (`in_use` is `true`), and is        /// not in a terminal state. Debug assertions verify these        /// preconditions.        ///        /// Calling release sets `in_use` to `false` and resets `loaded_bytes`        /// to zero. It does not overwrite or sanitize existing byte values in        /// the buffer. Historical tracking metrics, including the high-water        /// mark and the cumulative rejection count, remain intact across        /// release calls.        pub fn release(self: *Self) void {            std.debug.assert(self.phase == .steady);            std.debug.assert(self.in_use);            std.debug.assert(!self.terminal);            self.in_use = false;            self.loaded_bytes = 0;        }        /// Constructs and returns a snapshot of owner metrics and lifecycle        /// state as a `Spec.Status` structure.        ///        /// The method copies configured status fields by value under caller        /// serialization. Because the owner does not use atomic operations or        /// internal synchronization, this method does not produce a coherent        /// snapshot across concurrent unsynchronized access.        ///        /// The returned snapshot contains the following fields:        ///        /// * `phase`: Current lifecycle phase (`.initialization`, `.steady`, or        /// `.teardown`).        /// * `in_use`: Boolean flag indicating whether a borrowed buffer slice        /// is currently outstanding.        /// * `terminal`: Present on terminal owners to indicate whether        /// capacity exhaustion permanently sealed the owner.        /// * Configured limit field: Configured maximum byte limit derived from        /// capacity.        /// * `storage_bytes`: Total declared capacity of the buffer. Because        /// this value reflects declared specification capacity, it does not        /// represent a live allocation measurement and remains readable after        /// teardown.        /// * Configured loaded field: Number of admitted bytes currently held        /// by an active borrow. This field is zero whenever the owner is not in        /// use.        /// * Configured high-water field: Largest admitted byte count observed        /// across all successful reads since initialization. Oversized inputs        /// rejected during admission do not update this value.        /// * Configured rejected field: Cumulative saturating count of capacity        /// rejections.        pub fn status(self: *const Self) Spec.Status {            var result: Spec.Status = undefined;            result.phase = self.phase;            result.in_use = self.in_use;            if (comptime @hasField(Spec.Status, "terminal")) {                result.terminal = self.terminal;            }            @field(result, Spec.limit_field) = self.limitBytes();            result.storage_bytes = self.capacity.storage_bytes;            @field(result, Spec.loaded_field) = self.loaded_bytes;            @field(result, Spec.high_water_field) = self.high_water_bytes;            @field(result, Spec.rejected_field) = self.rejected_count;            return result;        }        /// Deinitializes the owner and frees its allocated byte buffer using        /// the provided allocator.        ///        /// Callers must supply the same allocator used for `init`. The method        /// verifies through debug assertions that the owner has not already        /// entered teardown and that no borrowed slice is currently in use        /// (`in_use` is `false`).        ///        /// Deinitialization transitions `phase` to `.teardown`, frees the        /// allocated memory slice, clears the internal buffer slice to empty,        /// and resets `loaded_bytes` to zero. Callers may invoke this method        /// while the owner is still in the `.initialization` phase to clean up        /// resources after a failed startup sequence. Cumulative metrics and        /// capacity declarations remain stored on the instance after        /// deinitialization completes.        pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {            std.debug.assert(self.phase != .teardown);            std.debug.assert(!self.in_use);            self.assertRegion();            self.phase = .teardown;            allocator.free(self.bytes);            self.bytes = &.{};            self.loaded_bytes = 0;        }        /// Verifies that the owner is ready to accept a new input operation.        ///        /// Debug assertions confirm that the owner resides in the `.steady`        /// phase, that buffer invariants hold, and that previous loaded bytes        /// did not exceed the limit. If the owner is marked terminal, the        /// function returns `Spec.capacity_error` without incrementing the        /// rejection counter. If a borrow is currently active, it returns        /// `Spec.in_use_error` without incrementing the rejection counter. When        /// available, debug assertions verify that `loaded_bytes` is zero.        fn requireAvailable(self: *Self) Exhaustion!void {            std.debug.assert(self.phase == .steady);            self.assertRegion();            std.debug.assert(self.loaded_bytes <= self.limitBytes());            if (self.terminal) return Spec.capacity_error;            if (self.in_use) return Spec.in_use_error;            std.debug.assert(self.loaded_bytes == 0);        }        /// Admits a specified number of bytes into the region or rejects the        /// payload if it exceeds the configured limit.        ///        /// Debug assertions verify that the owner is in steady operation        /// without an active borrow or terminal state, and that the requested        /// byte count does not exceed allocated storage. If `input_bytes`        /// exceeds the configured byte limit, the function invokes `reject`.        /// Otherwise, it marks the buffer as in use, records `loaded_bytes`,        /// updates `high_water_bytes` if the new length exceeds previous        /// admissions, and returns a borrowed slice over the admitted bytes.        fn admit(self: *Self, input_bytes: usize) Exhaustion![]const u8 {            std.debug.assert(self.phase == .steady);            std.debug.assert(!self.in_use);            std.debug.assert(!self.terminal);            std.debug.assert(input_bytes <= self.capacity.storage_bytes);            if (input_bytes > self.limitBytes()) return self.reject();            self.in_use = true;            self.loaded_bytes = input_bytes;            self.high_water_bytes = @max(self.high_water_bytes, input_bytes);            return self.bytes[0..input_bytes];        }        /// Records an input capacity rejection and updates owner overload        /// state.        ///        /// Debug assertions verify that the owner is in steady operation, is        /// not in use, is not already terminal, and holds zero loaded bytes. If        /// `Spec.overload` is configured as `.terminal`, the owner enters the        /// terminal state. The cumulative rejection counter is incremented        /// using saturating addition, and the function returns        /// `Spec.capacity_error`.        fn reject(self: *Self) Exhaustion {            std.debug.assert(self.phase == .steady);            std.debug.assert(!self.in_use);            std.debug.assert(!self.terminal);            std.debug.assert(self.loaded_bytes == 0);            self.terminal = Spec.overload == .terminal;            self.rejected_count +|= 1;            return Spec.capacity_error;        }        /// Helper function returning the configured byte limit stored on        /// `self.capacity` using the field name defined by `Spec.limit_field`.        fn limitBytes(self: *const Self) usize {            return @field(self.capacity, Spec.limit_field);        }        /// Helper function asserting that the backing byte slice length matches        /// `storage_bytes` and strictly exceeds the configured byte limit.        fn assertRegion(self: *const Self) void {            std.debug.assert(self.bytes.len == self.capacity.storage_bytes);            std.debug.assert(self.capacity.storage_bytes > self.limitBytes());        }    };}
Called byCallstest sourcelib.alloc.phase.src.input.onetest: one-region recoverable owner pr...test sourcelib.alloc.phase.src.input.onetest: one-region terminal owner acqui...private sourcelib.alloc.phase.src.input.onerequireAcquisitionprivate sourcelib.alloc.phase.src.input.onerequireSpecprivate sourcelib.choir.src.core.operation.storageassertRegioninputOneRegion
Static calls · unresolved targets: 4 · external targets: 12.

Source: lib/alloc/phase/src/input/one.zig:87

zig
/// Derives an instance of `Capacity` from a given `Limits` structure by adding/// one lookahead byte to the configured input limit.////// The input limit is retrieved from the field named by `limit_field` on/// `limits`. Both the limit field on `Limits` and `Capacity` and the/// `storage_bytes` field on `Capacity` must be typed as `usize`. When addition/// overflows `usize`, the function returns `error.CapacityOverflow`. A limit of/// zero derives a storage size of one byte.////// The returned `Capacity` structure initializes only the field named by/// `limit_field` and `storage_bytes`. Any additional fields present on/// `Capacity` remain undefined. Callers must keep `limit_field` distinct from/// `storage_bytes` so that writing `storage_bytes` does not overwrite the limit/// field.pub fn deriveCapacity(    comptime Limits: type,    comptime Capacity: type,    comptime limit_field: []const u8,    limits: Limits,) DeriveError!Capacity {    comptime requireCapacityTypes(Limits, Capacity, limit_field);    const limit_bytes = @field(limits, limit_field);    const storage_bytes = try alloc_phase.capacity.add(usize, limit_bytes, 1);    std.debug.assert(storage_bytes > limit_bytes);    std.debug.assert(storage_bytes != 0);    var capacity: Capacity = undefined;    @field(capacity, limit_field) = limit_bytes;    capacity.storage_bytes = storage_bytes;    return capacity;}
Called byCallsprivate sourcelib.alloc.phase.src.input.onetestCapacitytest sourcelib.alloc.phase.src.input.onetest: one-region capacity derives one...private sourcelib.alloc.phase.src.input.onerequireCapacityTypesinputderiveCapacity
Static calls · unresolved targets: 1 · external targets: 0.

Source: lib/alloc/phase/src/input/root.zig

zig
//! ## Package overview//!//! When we ingest external input from streams or files, we want to accept//! bounded payloads using a single reusable byte allocation without allocating//! on every message or resizing buffers on the fly. We configure an explicit//! upper bound on accepted length, allocate storage once, and reuse that//! storage across successive operations while detecting oversized inputs before//! admitting them.//!//! ## One buffer and lookahead//!//! The core challenge in bounded ingestion sits at the boundary of the limit.//! If we configure our system to accept at most `n` bytes and allocate an//! `n`-byte buffer, filling that buffer completely leaves an ambiguity: did the//! input stream end precisely at `n` bytes, or does more data remain waiting in//! the channel? To resolve whether the input fits or exceeds our boundary, this//! implementation reserves space for one extra byte. For an accepted limit of//! `n` bytes, the backing buffer holds `n + 1` bytes. When we read from the//! source into the buffer://!//! - If the source yields between 0 and `n` bytes before reaching end-of-file,//!   the input fits within our configured boundary and we admit it.//! - If the source yields `n + 1` bytes, the input exceeds our limit and we//!   reject it immediately, without allocating a second buffer.//!//! We term this calculation *capacity derivation*. The standard helper//! `deriveCapacity` computes this boundary for an owner. Given a configuration//! structure containing a byte limit field of type `usize`, it uses checked//! integer addition to compute `n + 1`. If adding one to the limit overflows//! `usize`, derivation fails with `error.CapacityOverflow`. When a caller//! configures a limit of zero, derivation reserves one byte, which allows an//! empty input to be distinguished from an input containing data.//!//! The `deriveCapacity` helper initializes only two fields in the resulting//! capacity record: the configured limit and the derived `storage_bytes`. The//! limit field name and `storage_bytes` must be distinct. Any additional fields//! declared on the capacity type remain undefined, so a custom capacity type//! that requires extra fields must populate them in a custom derivation//! function.//!//! The generic container `OneRegion(Spec)` produces an allocator-backed owner//! around this storage model. While `deriveCapacity` enforces the standard `n +//! 1` sizing rule, a custom derivation function may describe larger storage//! when required by domain constraints: derivation computes a `Capacity` value,//! while `init` allocates the storage. The owner asserts that `storage_bytes`//! strictly exceeds the configured input limit.//!//! ## A successful borrow and release//!//! Because a single byte buffer is reused across requests, concurrent access//! would corrupt in-flight payloads. An outstanding borrow represents temporary//! exclusive access granted to an admitted input. Until that borrow is//! relinquished, the owner enforces busy protection across subsequent//! acquisition and preflight calls.//!//! The lifecycle of an input owner progresses through three sequential phases://! initialization, steady operation, and teardown. Calling `init` enters the//! initialization phase, calling `activate` advances to steady operation, and//! calling `deinit` enters teardown. Calling `deinit` requires that no borrow//! remains outstanding. If startup fails prior to activation, `deinit` can be//! called directly from the initialization phase to free the buffer.//!//! During initialization, `init` derives the capacity and requests a single//! contiguous slice of `storage_bytes` from the provided allocator. If capacity//! derivation overflows or the allocator fails, `init` returns an error union//! of `DeriveError` and `std.mem.Allocator.Error`. Once allocated, the owner//! retains the byte slice but does not retain an allocator handle. In steady//! operation, the owner methods do not call the initialization allocator. The//! absence of a retained allocator on the owner does not prevent arbitrary//! readers or filesystem code from allocating dynamically or performing//! external work.//!//! Phase transitions are guarded by debug assertions (`std.debug.assert`),//! which verify that `activate` is called only from the initialization phase//! and that `deinit` is called with no active borrow. These debug assertions//! differ from the explicit wrong-phase panics enforced by the separate phase//! allocator.//!//! In steady operation, calling `read` ingests data into the buffer and admits//! the payload if the returned length does not exceed the configured limit. A//! successful read returns a borrowed constant slice (`[]const u8`) and sets//! the internal `in_use` flag. Even an empty zero-byte read establishes an//! active borrow and marks the owner busy. While `in_use` remains true, any//! attempt to read, window, or preflight another input returns `in_use_error`.//! This failure indicates a busy owner and does not increment the capacity//! rejection counter.//!//! When the caller finishes processing the borrowed slice, it invokes//! `release`. Calling `release` sets `in_use` to false and resets the loaded//! byte counter to zero. It does not zero or scrub the underlying memory, nor//! does it reset historical rejection counts or high-water marks.//!//! Because reads overwrite the backing buffer, a caller that needs to retain//! admitted bytes across subsequent operations must copy them into separate//! storage before calling `release`. A fixed stack array provides a convenient//! target for preserving small records without allocating heap memory.//!//! Copies of an owner struct share the underlying byte slice while duplicating//! internal bookkeeping. Because copies are not independent owners, callers//! must serialize operations and ensure that cleanup occurs exactly once.//! Calling `deinit` requires that no borrow remains outstanding, transitions//! the phase to teardown, and frees the slice using the same allocator passed//! during initialization. The owner provides no secondary abort or partial//! teardown routines.//!//! In the Issue tool, body storage adopts this borrow discipline. Its//! `BodySource` container pairs a borrowed slice of the input region with an//! optional pointer to the owner. When processing finishes or an empty body//! triggers an early exit, the consumer releases the borrow before reporting//! results. Command-line arguments provided directly in the process invocation//! bypass the input region entirely, leaving the buffer available for file or//! standard-input ingestion.//!//! ## Failure and recovery//!//! When an incoming payload exceeds the configured limit, the owner rejects the//! admission. How the owner responds to this overload depends on whether it is//! configured with a terminal or recoverable policy://!//! - A terminal owner treats an oversized input as a permanent boundary fault.//!   Upon rejection, it increments a saturating 64-bit rejection counter, sets//!   an internal `terminal` flag, and refuses all subsequent read attempts with//!   `capacity_error` without incrementing the counter again.//! - A recoverable owner increments the rejection counter but leaves `terminal`//!   false. Storage remains immediately available to accept another input//!   without an acknowledgement step.//!//! Recovery denotes the ability to reuse the owned memory buffer for a future//! request: it does not imply stream rewinding, transaction rollback, or//! automatic framing.//!//! When reading from a stream through `Reader.readSliceShort`, capacity//! rejection under the standard derivation helper occurs after reading up to//! `limit + 1` logical bytes into the buffer. The owner does not drain any//! remaining bytes left in the underlying stream. If an external caller//! attempts to read from that same stream again, the retry does not guarantee//! alignment with the start of a logical record. User reader implementations//! may also maintain internal buffers or perform dynamic allocations outside//! the owner's knowledge. If a stream encounters an I/O failure such as//! `ReadFailed`, the failure can consume source bytes and overwrite buffer//! contents. In that situation, no borrow is admitted and the owner's capacity//! rejection counter does not increment.//!//! To avoid reading unwanted bytes when an input size is known beforehand, an//! application can call `preflight`. The `preflight` method accepts an expected//! size as a 64-bit integer, checks that the owner is available, and verifies//! that the size fits within `usize` and does not exceed the limit. If the//! proposed size cannot be represented in `usize` or exceeds the limit,//! `preflight` rejects the request, updates rejection accounting, and returns//! `capacity_error`. A successful preflight verifies available space, but it//! neither reserves storage nor forms an atomic transaction with a subsequent//! read.//!//! Calling `status` returns a snapshot structure by value containing the//! current phase, the `in_use` flag, the configured limit, the declared storage//! size, the currently loaded bytes, the high-water mark of admitted bytes, the//! cumulative rejection count, and the terminal flag for terminal owners. The//! high-water mark records the largest admitted input, ignoring rejected//! attempts. Following `deinit`, the historical counters and declared capacity//! fields remain readable in the returned status snapshot, which means//! `storage_bytes` reports declared storage size rather than live retained heap//! memory.//!//! The Peek image decoding pipeline relies on a recoverable configuration. Its//! loader reads image files into the input buffer, holds the borrow while//! decoding pixel data into external image structures, and releases the owner//! immediately after decoding. If an oversized image is rejected, the owner//! remains active, enabling subsequent file reads to reuse the same memory//! allocation.//!//! ## Whole files versus windows//!//! Reading files introduces distinct concerns regarding whole-file ingestion//! versus positional slice inspection.//!//! Calling `readFile` reads an input file into the bounded buffer using the//! standard library directory interface. When reading an ordinary file whose//! size exceeds the limit, the reader fills the buffer prefix and the owner//! rejects the operation. The acquisition specification provides a//! configuration flag named `map_file_too_big`://!//! - When `map_file_too_big` is enabled, an underlying `FileTooBig` error//!   returned by the filesystem maps directly into the owner's capacity//!   rejection, incrementing the rejection counter and setting the terminal//!   flag if configured.//! - When `map_file_too_big` is disabled, `FileTooBig` propagates outward as a//!   filesystem error, bypassing rejection accounting and leaving the terminal//!   flag unset.//! - Other filesystem errors, such as missing files or access faults, propagate//!   unchanged under either setting without modifying capacity counters.//!//! When inputs exceed the capacity of our buffer, reading the entire file at//! once is impossible. Instead, we inspect bounded portions of the file using//! `readFileWindow`.//!//! Calling `readFileWindow` requires that file acquisition is enabled, that//! storage is available, and that the requested window length satisfies `0 <//! window_bytes <= limit`. The method reads up to `window_bytes + 1` bytes at a//! specified file offset, admits `min(read_count, window_bytes)`, and returns a//! `FileWindow` structure containing the borrowed slice and a boolean//! `complete` flag.//!//! If the file contains bytes beyond the requested window, the lookahead byte//! is populated, `complete` is set to false, and the admitted slice contains//! exactly `window_bytes`. An incomplete window read does not trigger a//! capacity rejection, even when the owner is configured as terminal. If the//! offset sits at end-of-file, a zero-byte read completes successfully and//! still establishes an active borrow. The `complete` flag describes only the//! result of this specific positional read: it does not provide an//! instantaneous file-length snapshot or guarantee that the file will not grow//! concurrently.//!//! Glom demonstrates how windowed ingestion coordinates with record framing.//! Glom ingests structured transcript files using a terminal input owner with//! preflight enabled. Because individual transcript records vary in length and//! files can grow large, its parser reads a positional window from the file. If//! `complete` is false, the window ended before the end of the file. Glom//! inspects the admitted bytes for the last newline character, processes//! complete lines up to that delimiter, releases the borrow, and advances its//! file offset to resume reading. If a maximum-sized window contains no newline//! delimiter at all, the consumer itself raises a record-framing error. Framing//! logic remains the responsibility of the consumer, while the input region//! guarantees only the bounded byte window.//!//! ## Declaration scope and interface shapes//!//! To integrate an input owner with verification and capacity tooling, we//! encapsulate its configuration within a `Spec` structure. A specification//! packages input limit and capacity types, error sets, status layout, enabled//! acquisition capabilities, overload policy, and a formal capacity//! `Declaration`.//!//! The status structure must declare exactly seven fields for recoverable//! owners or eight fields for terminal owners. While the generic checker//! validates the field count and types, it does not verify that custom field//! mappings are distinct from one another. We must supply distinct field names//! to prevent diagnostic collisions.//!//! The capacity `Declaration` establishes the structural contract of the owner//! for this example://!//! - Validation of `phase_static` requires valid seal and teardown bindings.//!   The tag describes a claim and does not govern actual allocation behavior//!   or enforce an operational lifetime. The limit source is marked as//!   `.caller`, indicating that limits are supplied at initialization.//! - The storage section specifies covered memory, naming the single//!   steady-state input buffer and describing its purpose. Excluded clauses//!   document runtime resources that sit outside the claim, such as stream//!   reader handles and destination parsing structures.//! - The capacity model defines an expression graph capturing the `n + 1`//!   derivation. An input node binds the limit field, an integer constant node//!   provides the literal 1, and an addition node sums them. An assertion//!   declares that total retained storage matches this expression.//! - The overload policy is declared as `.drop`, documenting that oversized//!   input is rejected while storage remains available for a later attempt. The//!   `.drop` policy does not preserve previously released payload bytes://!   subsequent reads can overwrite released bytes in the backing buffer.//! - Transitive and foreign operational risks are marked as `.open`,//!   acknowledging that reader streams or filesystem calls can incur effects//!   outside the region boundaries.//! - The declaration lists obligations for the capacity model and the overload//!   policy.//!//! When `OneRegion(Spec)` generates an owner, it constructs fresh bindings//! linking the owner type, the specification, and selectors for `activate` and//! `deinit`. It does not reuse any bindings declared on `Spec.claim`. Claim//! declarations and premise labels such as `.checked_semantic_fact` provide//! structural metadata for verification tools: they do not establish proven//! semantic facts or whole-program safety guarantees.//!//! We validate this generated structure at compile time using//! `alloc_phase.capacity.requireAllocatorRejectingOwnerShape(Storage)`. This//! function performs structural reflection, checking that the owner provides//! required lifecycle functions, exposes an exhaustion error set on receiver//! methods, and presents a compatible claim.//!//! The following test illustrates a specification and recoverable input owner://!//! ```zig//! const std = @import("std");//! const alloc_phase = @import("alloc_phase");//!//! pub const InputLimits = struct {//!     max_bytes: usize,//! };//!//! pub const InputCapacity = struct {//!     max_bytes: usize,//!     storage_bytes: usize,//!//!     pub fn derive(limits: InputLimits) alloc_phase.input.DeriveError!InputCapacity {//!         return alloc_phase.input.deriveCapacity(InputLimits, InputCapacity, "max_bytes", limits);//!     }//! };//!//! pub const InputExhaustion = error{//!     InputStorageBusy,//!     InputCapacityExceeded,//! };//!//! pub const InputStatus = struct {//!     phase: alloc_phase.capacity.Phase,//!     in_use: bool,//!     max_bytes: usize,//!     storage_bytes: usize,//!     loaded_bytes: usize,//!     high_water_bytes: usize,//!     rejected_count: u64,//! };//!//! pub const Spec = struct {//!     pub const Limits = InputLimits;//!     pub const Capacity = InputCapacity;//!     pub const Exhaustion = InputExhaustion;//!     pub const Status = InputStatus;//!     pub const DeriveError = alloc_phase.input.DeriveError;//!     pub const acquisition: alloc_phase.input.Acquisition = .{//!         .reader = true,//!         .preflight = true,//!     };//!     pub const overload: alloc_phase.input.Overload = .recoverable;//!     pub const limit_field = "max_bytes";//!     pub const loaded_field = "loaded_bytes";//!     pub const high_water_field = "high_water_bytes";//!     pub const rejected_field = "rejected_count";//!     pub const in_use_error: Exhaustion = error.InputStorageBusy;//!     pub const capacity_error: Exhaustion = error.InputCapacityExceeded;//!//!     pub const claim: alloc_phase.capacity.Declaration = .{//!         .source = .{//!             .id = "guide.recoverable_reader",//!             .kind = .phase_static,//!             .limit_source = .caller,//!             .storage = .{//!                 .covered = &.{//!                     .{//!                         .id = "reusable_input_buffer",//!                         .lifetime = .steady,//!                         .detail = "one reusable input and lookahead byte region",//!                     },//!                 },//!                 .excluded = &.{//!                     "stream reader buffering and allocator handles",//!                     "caller payload storage outside the borrowed window",//!                 },//!             },//!             .capacity = .{//!                 .inputs = &.{//!                     alloc_phase.capacity.bindInput(InputLimits, "max_bytes", "max_bytes"),//!                 },//!                 .type_selectors = &.{},//!                 .nodes = &.{//!                     .{ .input = 0 },//!                     .{ .constant = 1 },//!                     .{ .add = .{ .left = 0, .right = 1 } },//!                 },//!                 .assertions = &.{//!                     .{//!                         .scope = .closure_total,//!                         .measure = .retained,//!                         .relation = .exact,//!                         .expression = 2,//!                     },//!                 },//!             },//!             .overload = .{//!                 .kind = .drop,//!                 .detail = "oversized input is rejected while storage remains available for a later attempt",//!             },//!             .risks = .{//!                 .transitive = .{//!                     .status = .open,//!                     .detail = "stream operations may perform external allocations",//!                 },//!                 .foreign = .{//!                     .status = .open,//!                     .detail = "kernel stream handles remain unmanaged",//!                 },//!             },//!             .obligations = &.{//!                 .{ .key = "input_capacity_model", .role = .capacity_model },//!                 .{ .key = "input_overload_policy", .role = .overload },//!             },//!         },//!         .bindings = .{},//!     };//! };//!//! pub const Storage = alloc_phase.input.OneRegion(Spec);//!//! comptime {//!     alloc_phase.capacity.requireAllocatorRejectingOwnerShape(Storage);//! }//!//! test "recoverable input storage lifecycle, borrow discipline, and reuse" {//!     const allocator = std.testing.allocator;//!     var storage = try Storage.init(allocator, .{ .max_bytes = 5 });//!     defer storage.deinit(allocator);//!     defer if (storage.in_use) storage.release();//!//!     storage.activate();//!//!     var first_reader: std.Io.Reader = .fixed("hello");//!     const borrowed = try storage.read(&first_reader);//!//!     try std.testing.expectEqual(@as(usize, 5), borrowed.len);//!     try std.testing.expectEqualStrings("hello", borrowed);//!     try std.testing.expectError(error.InputStorageBusy, storage.preflight(0));//!//!     var preserved: [5]u8 = undefined;//!     @memcpy(&preserved, borrowed);//!//!     storage.release();//!//!     try std.testing.expectEqualStrings("hello", &preserved);//!//!     const status_after_release = storage.status();//!     try std.testing.expect(!status_after_release.in_use);//!     try std.testing.expectEqual(@as(usize, 0), status_after_release.loaded_bytes);//!     try std.testing.expectEqual(@as(usize, 5), status_after_release.high_water_bytes);//!     try std.testing.expectEqual(@as(u64, 0), status_after_release.rejected_count);//!//!     try std.testing.expectError(error.InputCapacityExceeded, storage.preflight(6));//!//!     const status_after_reject = storage.status();//!     try std.testing.expectEqual(@as(u64, 1), status_after_reject.rejected_count);//!//!     var second_reader: std.Io.Reader = .fixed("zig");//!     const second_borrow = try storage.read(&second_reader);//!//!     try std.testing.expectEqualStrings("zig", second_borrow);//!//!     const status_final = storage.status();//!     try std.testing.expect(status_final.in_use);//!     try std.testing.expectEqual(@as(usize, 3), status_final.loaded_bytes);//!     try std.testing.expectEqual(@as(usize, 5), status_final.high_water_bytes);//!//!     try std.testing.expectEqualStrings("hello", &preserved);//!//!     storage.release();//! }//! ```//!//! The source unit tests for `alloc_phase.input` assert capacity derivation//! from 31 to 32 bytes, overflow detection at integer limits, initialization//! failure under allocation faults, exact acceptance of fitting payloads, busy//! errors during active borrows, saturating rejection counters on terminal//! owners, and recoverable reuse following an oversized preflight check.//! Additional property tests assert `n + 1` allocation sizing for limits up to//! 4096 bytes, and consumer test suites exercise windowed reads alongside file//! boundary handling.const one = @import("one.zig");/// Packed boolean structure that enables specific input capabilities on an/// owner at compile time. All four fields default to `false`:////// * `reader`: Enables stream acquisition through `read`.////// * `file`: Enables filesystem acquisition through `readFile` and/// `readFileWindow`./// * `preflight`: Enables size admission checks through `preflight`./// * `map_file_too_big`: Maps `error.FileTooBig` from an underlying `readFile`/// call into a capacity rejection instead of propagating the raw I/O error.////// Because an owner must support at least one input mechanism, specification/// validation requires either `reader` or `file` to be enabled. Mapping/// file-size errors requires filesystem support, so `map_file_too_big` can be/// enabled only when `file` is also set to `true`. Individual acquisition/// methods verify their corresponding flags at compile time and raise a compile/// error when invoked without the required capability enabled.pub const Acquisition = one.Acquisition;/// Error set returned when capacity derivation fails.////// Members:////// * `CapacityOverflow`: Adding one lookahead byte to the configured byte limit/// overflowed the range of `usize`.pub const DeriveError = one.DeriveError;/// Constructs an allocator-backed owner type for a single reusable input buffer/// based on a static specification structure.////// The `Spec` type parameter must satisfy several structural requirements:////// * `Limits`: Structure defining input limits. It must contain the field/// designated by `limit_field` typed as `usize`./// * `Capacity`: Structure defining storage requirements. It must expose a/// `derive(limits: Limits) DeriveError!Capacity` function, the field named by/// `limit_field` typed as `usize`, and `storage_bytes` typed as `usize`./// * `DeriveError`: Error set returned by `Capacity.derive`./// * `Exhaustion`: Error set returned when storage cannot admit an input./// * `Status`: Reporting structure returned by `status`. It must be a struct/// containing exactly seven fields for recoverable owners or eight fields for/// terminal owners: `phase: alloc_phase.capacity.Phase`, `in_use: bool`,/// `storage_bytes: usize`, the mapped limit, loaded, and high-water fields/// typed as `usize`, the mapped rejection field typed as `u64`, and/// conditionally `terminal: bool` when `overload` is `terminal`./// * `acquisition`: An instance of `Acquisition` specifying enabled I/O/// capabilities./// * `overload`: An instance of `Overload` setting either `.terminal` or/// `.recoverable` behavior./// * Field mappings: `limit_field`, `loaded_field`, `high_water_field`, and/// `rejected_field` specify field names on `Capacity` or `Status`. Callers must/// supply distinct names for these fields. Compile-time validation verifies/// field presence and total field counts, but this validation does not prove/// that mapped field names are mutually distinct./// * Error instances: `in_use_error` and `capacity_error` must both have type/// `Spec.Exhaustion`./// * `claim`: A static `alloc_phase.capacity.Declaration` metadata descriptor.////// The owner asserts that `storage_bytes` strictly exceeds the configured byte/// limit. While standard `deriveCapacity` derivation provides an exact `limit +/// 1` layout, custom `Capacity.derive` implementations may describe larger/// storage: derivation computes a `Capacity` value, while `init` allocates.////// A successful read operation returns a borrowed `[]const u8` slice pointing/// directly into the owned buffer and marks the owner as in use, including when/// the input is empty. Borrowers must consume or copy these bytes elsewhere/// before calling `release`. Slices must not be accessed after releasing the/// owner.////// A struct copy shares allocated storage but duplicates internal bookkeeping./// Copies are not independent owners: transferring exclusive ownership requires/// callers to stop using the original. Callers must serialize operations and/// ensure cleanup occurs exactly once.////// The owner is not thread-safe and performs no internal synchronization./// Callers accessing an owner across threads must provide external mutual/// exclusion.////// Lifecycle checks across initialization, steady operation, and teardown are/// enforced through debug assertions rather than explicit always-executed phase/// panics.pub const OneRegion = one.OneRegion;/// Defines the policy applied when an input exceeds the configured capacity/// limit.////// Tags:////// * `terminal`: Permanently seals the owner upon capacity rejection. Any/// subsequent acquisition attempt returns the capacity error immediately/// without performing I/O or incrementing rejection counters./// * `recoverable`: Preserves owner availability across rejections. Oversized/// inputs increment the rejection counter but leave the underlying storage free/// for subsequent attempts.////// Recovery designates the ability to reuse the allocated storage for later/// inputs. It does not provide source-position rollback, record framing, or/// automatic input drainage.pub const Overload = one.Overload;/// Derives an instance of `Capacity` from a given `Limits` structure by adding/// one lookahead byte to the configured input limit.////// The input limit is retrieved from the field named by `limit_field` on/// `limits`. Both the limit field on `Limits` and `Capacity` and the/// `storage_bytes` field on `Capacity` must be typed as `usize`. When addition/// overflows `usize`, the function returns `error.CapacityOverflow`. A limit of/// zero derives a storage size of one byte.////// The returned `Capacity` structure initializes only the field named by/// `limit_field` and `storage_bytes`. Any additional fields present on/// `Capacity` remain undefined. Callers must keep `limit_field` distinct from/// `storage_bytes` so that writing `storage_bytes` does not overwrite the limit/// field.pub const deriveCapacity = one.deriveCapacity;

Source: lib/alloc/phase/src/root.zig:115

zig
/// Bounded reusable input buffer storage (`OneRegion`). Configures a reusable/// byte buffer, enforces exclusive borrow and release discipline, and provides/// recoverable or terminal overload options. See/// [input/root.zig](input/root.zig).pub const input = @import("input/root.zig");

Audit

Definitions6
Public names6
Members7
Version26.7.0
Revisiondaab053ee433