tiny.wayland.stream
Defined in tiny.wayland.
API (31)
Actions
Public operations.
Capacity.deriveInbox.appendOwnedInbox.commitReceivedInbox.consumeInbox.deinitInbox.initInbox.peekInbox.peekDescriptorsInbox.prepareReceiveInbox.queuedByteCountInbox.queuedDescriptorCountInbox.statusInbox.takeDescriptorOutbox.deinitOutbox.flushOutbox.initOutbox.pendingByteCountOutbox.pendingDescriptorCountOutbox.queueOwnedOutbox.status
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
Source
Source: lib/wayland/src/stream/inbox.zig:8
Source: lib/wayland/src/stream/inbox.zig:14
zig
pub const Inbox = struct { session_allocator: std.mem.Allocator, bytes: []u8, descriptors: []sys.fd.Descriptor, byte_count: usize = 0, descriptor_count: usize = 0, byte_offset: usize = 0, descriptor_offset: usize = 0, byte_capacity_rejection_count: u64 = 0, descriptor_capacity_rejection_count: u64 = 0, pub fn init( session_allocator: std.mem.Allocator, capacity: storage.Capacity, ) std.mem.Allocator.Error!Inbox { const bytes = try session_allocator.alloc(u8, capacity.inbound_byte_count); errdefer session_allocator.free(bytes); return .{ .session_allocator = session_allocator, .bytes = bytes, .descriptors = try session_allocator.alloc( sys.fd.Descriptor, capacity.inbound_descriptor_count, ), }; } pub fn deinit(self: *Inbox) void { self.assertValid(); closeAll(self.descriptors[self.descriptor_offset..self.descriptor_count]); self.session_allocator.free(self.bytes); if (self.descriptors.len != 0) self.session_allocator.free(self.descriptors); self.* = undefined; } pub fn appendOwned( self: *Inbox, bytes: []const u8, descriptors: []const sys.fd.Descriptor, ) storage.StorageError!void { self.compact(); var failure: ?storage.StorageError = null; if (bytes.len > self.bytes.len - self.byte_count) { self.byte_capacity_rejection_count +|= 1; failure = error.InboundByteCapacityExceeded; } if (descriptors.len > self.descriptors.len - self.descriptor_count) { self.descriptor_capacity_rejection_count +|= 1; if (failure == null) failure = error.InboundDescriptorCapacityExceeded; } if (failure) |err| return err; @memcpy(self.bytes[self.byte_count..][0..bytes.len], bytes); @memcpy( self.descriptors[self.descriptor_count..][0..descriptors.len], descriptors, ); self.byte_count += bytes.len; self.descriptor_count += descriptors.len; self.assertValid(); } pub fn prepareReceive( self: *Inbox, maximum_byte_count: usize, ) storage.StorageError![]u8 { std.debug.assert(maximum_byte_count > 0); self.compact(); const available = self.bytes.len - self.byte_count; if (available == 0) { self.byte_capacity_rejection_count +|= 1; return error.InboundByteCapacityExceeded; } return self.bytes[self.byte_count..][0..@min(available, maximum_byte_count)]; } pub fn commitReceived( self: *Inbox, byte_count: usize, descriptors: []const sys.fd.Descriptor, ) storage.StorageError!void { std.debug.assert(byte_count > 0); std.debug.assert(byte_count <= self.bytes.len - self.byte_count); if (descriptors.len > self.descriptors.len - self.descriptor_count) { self.descriptor_capacity_rejection_count +|= 1; return error.InboundDescriptorCapacityExceeded; } @memcpy( self.descriptors[self.descriptor_count..][0..descriptors.len], descriptors, ); self.byte_count += byte_count; self.descriptor_count += descriptors.len; self.assertValid(); } pub fn peek(self: *const Inbox) wire.Error!?Frame { self.assertValid(); const available = self.bytes[self.byte_offset..self.byte_count]; if (available.len < wire.header_size) return null; const header = try wire.decode(available[0..wire.header_size]); if (available.len < header.size) return null; return .{ .header = header, .bytes = available[0..header.size], .payload = available[wire.header_size..header.size], }; } pub fn consume(self: *Inbox) (wire.Error || error{IncompleteMessage})!void { self.assertValid(); const frame = (try self.peek()) orelse return error.IncompleteMessage; self.byte_offset += frame.header.size; if (self.byte_offset == self.byte_count) { self.byte_count = 0; self.byte_offset = 0; } self.assertValid(); } pub fn takeDescriptor(self: *Inbox) ?sys.fd.Descriptor { self.assertValid(); if (self.descriptor_offset == self.descriptor_count) return null; const descriptor = self.descriptors[self.descriptor_offset]; self.descriptor_offset += 1; if (self.descriptor_offset == self.descriptor_count) { self.descriptor_count = 0; self.descriptor_offset = 0; } self.assertValid(); return descriptor; } pub fn peekDescriptors(self: *const Inbox, count: usize) ?[]const sys.fd.Descriptor { if (count > self.queuedDescriptorCount()) return null; return self.descriptors[self.descriptor_offset..self.descriptor_count][0..count]; } pub fn queuedByteCount(self: *const Inbox) usize { return self.byte_count - self.byte_offset; } pub fn queuedDescriptorCount(self: *const Inbox) usize { return self.descriptor_count - self.descriptor_offset; } pub fn status(self: *const Inbox) storage.Status { return .{ .inbound_byte_capacity_rejection_count = self.byte_capacity_rejection_count, .inbound_descriptor_capacity_rejection_count = self.descriptor_capacity_rejection_count, }; } fn compact(self: *Inbox) void { storage.compactSlice(u8, self.bytes, &self.byte_count, &self.byte_offset); storage.compactSlice( sys.fd.Descriptor, self.descriptors, &self.descriptor_count, &self.descriptor_offset, ); } fn assertValid(self: *const Inbox) void { std.debug.assert(self.byte_offset <= self.byte_count); std.debug.assert(self.byte_count <= self.bytes.len); std.debug.assert(self.descriptor_offset <= self.descriptor_count); std.debug.assert(self.descriptor_count <= self.descriptors.len); }};Source: lib/wayland/src/stream/outbox.zig:8
zig
pub const FlushStatus = enum { drained, pending,};Source: lib/wayland/src/stream/outbox.zig:13
zig
pub const Outbox = struct { session_allocator: std.mem.Allocator, bytes: []u8, descriptors: []sys.fd.Descriptor, byte_count: usize = 0, descriptor_count: usize = 0, byte_offset: usize = 0, descriptor_offset: usize = 0, byte_capacity_rejection_count: u64 = 0, descriptor_capacity_rejection_count: u64 = 0, pub fn init( session_allocator: std.mem.Allocator, capacity: storage.Capacity, ) std.mem.Allocator.Error!Outbox { const bytes = try session_allocator.alloc(u8, capacity.outbound_byte_count); errdefer session_allocator.free(bytes); return .{ .session_allocator = session_allocator, .bytes = bytes, .descriptors = try session_allocator.alloc( sys.fd.Descriptor, capacity.outbound_descriptor_count, ), }; } pub fn deinit(self: *Outbox) void { self.assertValid(); closeAll(self.descriptors[self.descriptor_offset..self.descriptor_count]); self.session_allocator.free(self.bytes); if (self.descriptors.len != 0) self.session_allocator.free(self.descriptors); self.* = undefined; } pub fn queueOwned( self: *Outbox, object_id: u32, opcode: u16, payload: []const u8, descriptors: []const sys.fd.Descriptor, ) (wire.Error || storage.StorageError || error{TooManyDescriptors})!void { if (descriptors.len > sys.ancillary.maximum_descriptors) return error.TooManyDescriptors; const header = try wire.Header.init(object_id, opcode, payload.len); var encoded: [wire.header_size]u8 = undefined; try header.encode(&encoded); self.compact(); const message_byte_count = encoded.len + payload.len; var failure: ?storage.StorageError = null; if (message_byte_count > self.bytes.len - self.byte_count) { self.byte_capacity_rejection_count +|= 1; failure = error.OutboundByteCapacityExceeded; } if (descriptors.len > self.descriptors.len - self.descriptor_count) { self.descriptor_capacity_rejection_count +|= 1; if (failure == null) failure = error.OutboundDescriptorCapacityExceeded; } if (failure) |err| return err; @memcpy(self.bytes[self.byte_count..][0..encoded.len], &encoded); self.byte_count += encoded.len; @memcpy(self.bytes[self.byte_count..][0..payload.len], payload); self.byte_count += payload.len; @memcpy( self.descriptors[self.descriptor_count..][0..descriptors.len], descriptors, ); self.descriptor_count += descriptors.len; self.assertValid(); } pub fn flush(self: *Outbox, socket: sys.fd.Descriptor) !FlushStatus { while (self.byte_offset < self.byte_count) { const pending_bytes = self.bytes[self.byte_offset..self.byte_count]; const pending_descriptors = self.descriptors[self.descriptor_offset..self.descriptor_count]; const descriptor_count = @min(pending_descriptors.len, sys.ancillary.maximum_descriptors); const bytes = if (pending_descriptors.len > descriptor_count) pending_bytes[0..1] else pending_bytes; const descriptors = pending_descriptors[0..descriptor_count]; const sent = sys.ancillary.send(socket, bytes, descriptors) catch |err| switch (err) { error.WouldBlock => return .pending, else => return err, }; if (sent == 0) return error.SendFailed; closeAll(descriptors); self.descriptor_offset += descriptors.len; self.byte_offset += sent; self.assertValid(); } std.debug.assert(self.descriptor_offset == self.descriptor_count); self.byte_count = 0; self.descriptor_count = 0; self.byte_offset = 0; self.descriptor_offset = 0; self.assertValid(); return .drained; } pub fn pendingByteCount(self: *const Outbox) usize { return self.byte_count - self.byte_offset; } pub fn pendingDescriptorCount(self: *const Outbox) usize { return self.descriptor_count - self.descriptor_offset; } pub fn status(self: *const Outbox) storage.Status { return .{ .outbound_byte_capacity_rejection_count = self.byte_capacity_rejection_count, .outbound_descriptor_capacity_rejection_count = self.descriptor_capacity_rejection_count, }; } fn compact(self: *Outbox) void { storage.compactSlice(u8, self.bytes, &self.byte_count, &self.byte_offset); storage.compactSlice( sys.fd.Descriptor, self.descriptors, &self.descriptor_count, &self.descriptor_offset, ); } fn assertValid(self: *const Outbox) void { std.debug.assert(self.byte_offset <= self.byte_count); std.debug.assert(self.byte_count <= self.bytes.len); std.debug.assert(self.descriptor_offset <= self.descriptor_count); std.debug.assert(self.descriptor_count <= self.descriptors.len); }};Source: lib/wayland/src/stream/storage.zig:23
zig
pub const Capacity = struct { inbound_byte_count: usize, inbound_descriptor_count: usize, inbound_descriptor_bytes: usize, inbound_storage_bytes: usize, outbound_byte_count: usize, outbound_descriptor_count: usize, outbound_descriptor_bytes: usize, outbound_storage_bytes: usize, total_requested_bytes: usize, pub fn derive(limits: Limits) CapacityError!Capacity { if (limits.inbound_byte_count < wire.header_size) { return error.InboundByteStorageTooSmall; } if (limits.outbound_byte_count < wire.header_size) { return error.OutboundByteStorageTooSmall; } const inbound_descriptor_bytes = std.math.mul( usize, limits.inbound_descriptor_count, @sizeOf(sys.fd.Descriptor), ) catch return error.CapacityOverflow; const inbound_storage_bytes = std.math.add( usize, limits.inbound_byte_count, inbound_descriptor_bytes, ) catch return error.CapacityOverflow; const outbound_descriptor_bytes = std.math.mul( usize, limits.outbound_descriptor_count, @sizeOf(sys.fd.Descriptor), ) catch return error.CapacityOverflow; const outbound_storage_bytes = std.math.add( usize, limits.outbound_byte_count, outbound_descriptor_bytes, ) catch return error.CapacityOverflow; const total_requested_bytes = std.math.add( usize, inbound_storage_bytes, outbound_storage_bytes, ) catch return error.CapacityOverflow; return .{ .inbound_byte_count = limits.inbound_byte_count, .inbound_descriptor_count = limits.inbound_descriptor_count, .inbound_descriptor_bytes = inbound_descriptor_bytes, .inbound_storage_bytes = inbound_storage_bytes, .outbound_byte_count = limits.outbound_byte_count, .outbound_descriptor_count = limits.outbound_descriptor_count, .outbound_descriptor_bytes = outbound_descriptor_bytes, .outbound_storage_bytes = outbound_storage_bytes, .total_requested_bytes = total_requested_bytes, }; }};Source: lib/wayland/src/stream/storage.zig:17
zig
pub const CapacityError = error{ InboundByteStorageTooSmall, OutboundByteStorageTooSmall, CapacityOverflow,};Source: lib/wayland/src/stream/storage.zig:10
zig
pub const Limits = struct { inbound_byte_count: usize = default_byte_count, inbound_descriptor_count: usize = default_descriptor_count, outbound_byte_count: usize = default_byte_count, outbound_descriptor_count: usize = default_descriptor_count,};Source: lib/wayland/src/stream/storage.zig:87
zig
pub const Status = struct { inbound_byte_capacity_rejection_count: u64 = 0, inbound_descriptor_capacity_rejection_count: u64 = 0, outbound_byte_capacity_rejection_count: u64 = 0, outbound_descriptor_capacity_rejection_count: u64 = 0,};Source: lib/wayland/src/stream/storage.zig:80
zig
pub const StorageError = error{ InboundByteCapacityExceeded, InboundDescriptorCapacityExceeded, OutboundByteCapacityExceeded, OutboundDescriptorCapacityExceeded,};Source: lib/wayland/src/root.zig:67
zig
pub const stream = @import("stream/root.zig");Source: lib/wayland/src/stream/root.zig
zig
const inbox = @import("inbox.zig");const outbox = @import("outbox.zig");const storage = @import("storage.zig");pub const FlushStatus = outbox.FlushStatus;pub const Frame = inbox.Frame;pub const Inbox = inbox.Inbox;pub const Outbox = outbox.Outbox;pub const Limits = storage.Limits;pub const Capacity = storage.Capacity;pub const CapacityError = storage.CapacityError;pub const StorageError = storage.StorageError;pub const Status = storage.Status;pub const default_byte_count = storage.default_byte_count;pub const default_descriptor_count = storage.default_descriptor_count;Source: lib/wayland/src/stream/storage.zig:8
Audit
| Definitions | 31 |
|---|---|
| Public names | 31 |
| Members | 47 |
| Version | 26.7.0 |
| Revision | daab053ee433 |