tiny.wayland.protocol.value
Defined in protocol.
API (53)
Actions
Public operations.
Decoder.arrayDecoder.descriptorDecoder.dynamicNewIdDecoder.finishDecoder.fixedDecoder.initDecoder.newIdDecoder.objectDecoder.optionalObjectDecoder.optionalStringDecoder.signedDecoder.stringDecoder.unsignedEncoded.opcodeEncoder.arrayEncoder.deinitEncoder.descriptorBorrowedEncoder.dynamicNewIdEncoder.finishEncoder.fixedEncoder.initEncoder.newIdEncoder.objectEncoder.optionalObjectEncoder.optionalStringEncoder.resetEncoder.signedEncoder.statusEncoder.stringEncoder.unsignedEncoderCapacity.deriveFixed.fromIntFixed.fromRawFixed.toF64NewId.initObjectId.init
Types and contracts
Public types and contracts.
DecodeErrorDecoderDynamicNewIdEncodedEncoderEncoderCapacityEncoderCapacityErrorEncoderErrorEncoderLimitsEncoderStatusEncoderStorageErrorFixedNewIdObjectId
Namespaces
Public namespaces.
Values and defaults
Public values and defaults.
Source
Source: lib/wayland/src/protocol/value/decode.zig:24
pub const Decoder = struct { metadata: *const protocol.schema.Message, payload: []const u8, descriptors: []const sys.fd.Descriptor, byte_offset: usize = 0, descriptor_offset: usize = 0, pub fn init( metadata: *const protocol.schema.Message, payload: []const u8, descriptors: []const sys.fd.Descriptor, ) Error!Decoder { if (payload.len % 4 != 0) return error.InvalidAlignment; if (payload.len > value.maximum_payload_size) return error.MessageTooLarge; if (payload.len < metadata.minimum_payload_size) return error.PayloadTooSmall; if (descriptors.len != metadata.descriptor_count) return error.DescriptorCountMismatch; return .{ .metadata = metadata, .payload = payload, .descriptors = descriptors, }; } pub fn signed(self: *Decoder) Error!i32 { const bytes = try self.word(); return std.mem.readInt(i32, bytes, builtin.cpu.arch.endian()); } pub fn unsigned(self: *Decoder) Error!u32 { const bytes = try self.word(); return std.mem.readInt(u32, bytes, builtin.cpu.arch.endian()); } pub fn fixed(self: *Decoder) Error!value.Fixed { return .fromRaw(try self.signed()); } pub fn string(self: *Decoder) Error![]const u8 { return (try self.optionalString()) orelse error.InvalidString; } pub fn optionalString(self: *Decoder) Error!?[]const u8 { const length = try self.unsigned(); if (length == 0) return null; const bytes = try self.delimited(length); if (bytes[bytes.len - 1] != 0) return error.InvalidString; const text = bytes[0 .. bytes.len - 1]; if (std.mem.indexOfScalar(u8, text, 0) != null) return error.InvalidString; if (!std.unicode.utf8ValidateSlice(text)) return error.InvalidUtf8; return text; } pub fn object(self: *Decoder) Error!value.ObjectId { return value.ObjectId.init(try self.unsigned()) catch return error.InvalidObject; } pub fn optionalObject(self: *Decoder) Error!?value.ObjectId { const raw = try self.unsigned(); return if (raw == 0) null else value.ObjectId.init(raw) catch return error.InvalidObject; } pub fn newId(self: *Decoder) Error!value.NewId { return value.NewId.init(try self.unsigned()) catch return error.InvalidNewId; } pub fn dynamicNewId(self: *Decoder) Error!value.DynamicNewId { const interface = try self.string(); if (interface.len == 0) return error.InvalidInterface; const version = try self.unsigned(); if (version == 0) return error.InvalidVersion; return .{ .interface = interface, .version = version, .id = try self.newId(), }; } pub fn array(self: *Decoder) Error![]const u8 { return self.delimited(try self.unsigned()); } pub fn descriptor(self: *Decoder) Error!sys.fd.Descriptor { if (self.descriptor_offset == self.descriptors.len) return error.IncompletePayload; const item = self.descriptors[self.descriptor_offset]; if (item < 0) return error.InvalidDescriptor; self.descriptor_offset += 1; return item; } pub fn finish(self: *const Decoder) Error!void { if (self.byte_offset != self.payload.len) return error.TrailingPayload; if (self.descriptor_offset != self.descriptors.len) return error.TrailingDescriptors; } fn word(self: *Decoder) Error!*const [4]u8 { if (self.payload.len - self.byte_offset < 4) return error.IncompletePayload; const bytes: *const [4]u8 = self.payload[self.byte_offset..][0..4]; self.byte_offset += 4; return bytes; } fn delimited(self: *Decoder, length: u32) Error![]const u8 { const rounded = std.math.add(usize, length, 3) catch return error.IncompletePayload; const padded_len = rounded & ~@as(usize, 3); if (padded_len > self.payload.len - self.byte_offset) return error.IncompletePayload; const bytes = self.payload[self.byte_offset..][0..length]; self.byte_offset += padded_len; return bytes; }};Source: lib/wayland/src/protocol/value/decode.zig:7
pub const Error = error{ DescriptorCountMismatch, IncompletePayload, InvalidAlignment, InvalidDescriptor, InvalidInterface, InvalidNewId, InvalidObject, InvalidString, InvalidUtf8, InvalidVersion, MessageTooLarge, PayloadTooSmall, TrailingDescriptors, TrailingPayload,};Source: lib/wayland/src/protocol/value/encode.zig:17
pub const Capacity = struct { payload_byte_count: usize, descriptor_count: usize, descriptor_bytes: usize, total_requested_bytes: usize, pub fn derive(limits: Limits) CapacityError!Capacity { if (limits.payload_byte_count > value.maximum_payload_size) { return error.PayloadStorageTooLarge; } if (limits.descriptor_count > sys.ancillary.maximum_descriptors) { return error.DescriptorStorageTooLarge; } const descriptor_bytes = std.math.mul( usize, limits.descriptor_count, @sizeOf(sys.fd.Descriptor), ) catch return error.CapacityOverflow; const total_requested_bytes = std.math.add( usize, limits.payload_byte_count, descriptor_bytes, ) catch return error.CapacityOverflow; return .{ .payload_byte_count = limits.payload_byte_count, .descriptor_count = limits.descriptor_count, .descriptor_bytes = descriptor_bytes, .total_requested_bytes = total_requested_bytes, }; }};Source: lib/wayland/src/protocol/value/encode.zig:11
pub const CapacityError = error{ PayloadStorageTooLarge, DescriptorStorageTooLarge, CapacityOverflow,};Source: lib/wayland/src/protocol/value/encode.zig:75
pub const Encoder = struct { session_allocator: std.mem.Allocator, bytes: []u8, descriptors: []sys.fd.Descriptor, byte_count: usize = 0, descriptor_count: usize = 0, payload_capacity_rejection_count: u64 = 0, descriptor_capacity_rejection_count: u64 = 0, pub fn init( session_allocator: std.mem.Allocator, capacity: Capacity, ) std.mem.Allocator.Error!Encoder { const bytes = try session_allocator.alloc(u8, capacity.payload_byte_count); errdefer if (bytes.len != 0) session_allocator.free(bytes); return .{ .session_allocator = session_allocator, .bytes = bytes, .descriptors = try session_allocator.alloc( sys.fd.Descriptor, capacity.descriptor_count, ), }; } pub fn deinit(self: *Encoder) void { self.assertValid(); if (self.bytes.len != 0) self.session_allocator.free(self.bytes); if (self.descriptors.len != 0) self.session_allocator.free(self.descriptors); self.* = undefined; } pub fn reset(self: *Encoder) void { self.assertValid(); self.byte_count = 0; self.descriptor_count = 0; } pub fn signed(self: *Encoder, item: i32) Error!void { var bytes: [4]u8 = undefined; std.mem.writeInt(i32, &bytes, item, builtin.cpu.arch.endian()); try self.appendBytes(&bytes); } pub fn unsigned(self: *Encoder, item: u32) Error!void { var bytes: [4]u8 = undefined; std.mem.writeInt(u32, &bytes, item, builtin.cpu.arch.endian()); try self.appendBytes(&bytes); } pub fn fixed(self: *Encoder, item: value.Fixed) Error!void { try self.signed(item.raw); } pub fn string(self: *Encoder, text: []const u8) Error!void { try validateString(text); try self.lengthDelimited(text, true); } pub fn optionalString(self: *Encoder, text: ?[]const u8) Error!void { if (text) |present| return self.string(present); try self.unsigned(0); } pub fn object(self: *Encoder, id: value.ObjectId) Error!void { try self.unsigned(id.raw); } pub fn optionalObject(self: *Encoder, id: ?value.ObjectId) Error!void { try self.unsigned(if (id) |present| present.raw else 0); } pub fn newId(self: *Encoder, id: value.NewId) Error!void { try self.unsigned(id.raw); } pub fn dynamicNewId( self: *Encoder, interface: []const u8, version: u32, id: value.NewId, ) Error!void { if (interface.len == 0) return error.InvalidInterface; if (version == 0) return error.InvalidVersion; const byte_mark = self.byte_count; errdefer self.byte_count = byte_mark; try self.string(interface); try self.unsigned(version); try self.newId(id); } pub fn array(self: *Encoder, bytes: []const u8) Error!void { try self.lengthDelimited(bytes, false); } pub fn descriptorBorrowed(self: *Encoder, descriptor: sys.fd.Descriptor) Error!void { self.assertValid(); if (descriptor < 0) return error.InvalidDescriptor; if (self.descriptor_count == sys.ancillary.maximum_descriptors) { return error.TooManyDescriptors; } if (self.descriptor_count == self.descriptors.len) { self.descriptor_capacity_rejection_count +|= 1; return error.DescriptorCapacityExceeded; } self.descriptors[self.descriptor_count] = descriptor; self.descriptor_count += 1; } pub fn finish( self: *const Encoder, metadata: *const @import("../root.zig").schema.Message, ) Error!value.Encoded { self.assertValid(); if (self.byte_count < metadata.minimum_payload_size) return error.PayloadTooSmall; if (self.byte_count % 4 != 0) unreachable; if (self.descriptor_count != metadata.descriptor_count) { return error.DescriptorCountMismatch; } return .{ .metadata = metadata, .payload = self.bytes[0..self.byte_count], .descriptors = self.descriptors[0..self.descriptor_count], }; } pub fn status(self: *const Encoder) Status { self.assertValid(); return .{ .payload_capacity_rejection_count = self.payload_capacity_rejection_count, .descriptor_capacity_rejection_count = self.descriptor_capacity_rejection_count, }; } fn appendBytes(self: *Encoder, bytes: []const u8) Error!void { try self.ensurePayloadCapacity(bytes.len); @memcpy(self.bytes[self.byte_count..][0..bytes.len], bytes); self.byte_count += bytes.len; } fn lengthDelimited(self: *Encoder, bytes: []const u8, terminal_zero: bool) Error!void { const logical_len = std.math.add(usize, bytes.len, @intFromBool(terminal_zero)) catch { return error.MessageTooLarge; }; if (logical_len > std.math.maxInt(u32)) return error.MessageTooLarge; const rounded_len = std.math.add(usize, logical_len, 3) catch return error.MessageTooLarge; const padded_len = rounded_len & ~@as(usize, 3); const encoded_len = std.math.add(usize, 4, padded_len) catch return error.MessageTooLarge; try self.ensurePayloadCapacity(encoded_len); var length_bytes: [4]u8 = undefined; std.mem.writeInt(u32, &length_bytes, @intCast(logical_len), builtin.cpu.arch.endian()); @memcpy(self.bytes[self.byte_count..][0..length_bytes.len], &length_bytes); self.byte_count += length_bytes.len; @memcpy(self.bytes[self.byte_count..][0..bytes.len], bytes); self.byte_count += bytes.len; if (terminal_zero) { self.bytes[self.byte_count] = 0; self.byte_count += 1; } const padding = padded_len - logical_len; @memset(self.bytes[self.byte_count..][0..padding], 0); self.byte_count += padding; } fn ensurePayloadCapacity(self: *Encoder, additional: usize) Error!void { self.assertValid(); const total = std.math.add(usize, self.byte_count, additional) catch { return error.MessageTooLarge; }; if (total > value.maximum_payload_size) return error.MessageTooLarge; if (total > self.bytes.len) { self.payload_capacity_rejection_count +|= 1; return error.PayloadCapacityExceeded; } } fn assertValid(self: *const Encoder) void { std.debug.assert(self.byte_count <= self.bytes.len); std.debug.assert(self.descriptor_count <= self.descriptors.len); }};Source: lib/wayland/src/protocol/value/encode.zig:6
pub const Limits = struct { payload_byte_count: usize = value.maximum_payload_size, descriptor_count: usize = sys.ancillary.maximum_descriptors,};Source: lib/wayland/src/protocol/value/encode.zig:54
pub const Status = struct { payload_capacity_rejection_count: u64 = 0, descriptor_capacity_rejection_count: u64 = 0,};Source: lib/wayland/src/protocol/value/encode.zig:49
pub const StorageError = error{ PayloadCapacityExceeded, DescriptorCapacityExceeded,};Source: lib/wayland/src/protocol/value/types.zig:41
pub const DynamicNewId = struct { interface: []const u8, version: u32, id: NewId,};Source: lib/wayland/src/protocol/value/types.zig:47
pub const Encoded = struct { metadata: *const protocol.schema.Message, payload: []const u8, descriptors: []const sys.fd.Descriptor, pub fn opcode(self: Encoded) u16 { return self.metadata.opcode; }};Source: lib/wayland/src/protocol/value/types.zig:25
pub const Fixed = struct { raw: i32, pub fn fromRaw(raw: i32) Fixed { return .{ .raw = raw }; } pub fn fromInt(value: i32) error{Overflow}!Fixed { return .{ .raw = std.math.mul(i32, value, 256) catch return error.Overflow }; } pub fn toF64(self: Fixed) f64 { return @as(f64, @floatFromInt(self.raw)) / 256.0; }};Source: lib/wayland/src/protocol/value/types.zig:16
pub const NewId = struct { raw: u32, pub fn init(raw: u32) error{InvalidNewId}!NewId { if (raw == 0) return error.InvalidNewId; return .{ .raw = raw }; }};Source: lib/wayland/src/protocol/value/types.zig:7
pub const ObjectId = struct { raw: u32, pub fn init(raw: u32) error{InvalidObject}!ObjectId { if (raw == 0) return error.InvalidObject; return .{ .raw = raw }; }};Source: lib/wayland/src/protocol/value/encode.zig:73
pub const Error = StorageError || ProtocolError;Source: lib/wayland/src/protocol/value/encode.zig:59
pub const default_capacity = Capacity.derive(.{}) catch unreachable;Source: lib/wayland/src/protocol/value/types.zig:5
pub const maximum_payload_size = (std.math.maxInt(u16) & ~@as(u16, 3)) - 8;Source: lib/wayland/src/protocol/root.zig:3
pub const value = @import("value/root.zig");Source: lib/wayland/src/protocol/value/root.zig
const decode = @import("decode.zig");const encode = @import("encode.zig");const types = @import("types.zig");pub const validate = @import("validate.zig");pub const Decoder = decode.Decoder;pub const DecodeError = decode.Error;pub const Encoder = encode.Encoder;pub const EncoderError = encode.Error;pub const EncoderLimits = encode.Limits;pub const EncoderCapacity = encode.Capacity;pub const EncoderCapacityError = encode.CapacityError;pub const EncoderStorageError = encode.StorageError;pub const EncoderStatus = encode.Status;pub const default_encoder_capacity = encode.default_capacity;pub const DynamicNewId = types.DynamicNewId;pub const Encoded = types.Encoded;pub const Fixed = types.Fixed;pub const NewId = types.NewId;pub const ObjectId = types.ObjectId;pub const maximum_payload_size = types.maximum_payload_size;Complete caller list for protocol.value.Decoder.unsigned
8 direct callers.
tiny.wayland.protocol.value.Decoder.array[method] atlib/wayland/src/protocol/value/decode.zig:101tiny.wayland.protocol.value.Decoder.dynamicNewId[method] atlib/wayland/src/protocol/value/decode.zig:89tiny.wayland.protocol.value.Decoder.newId[method] atlib/wayland/src/protocol/value/decode.zig:85tiny.wayland.protocol.value.Decoder.object[method] atlib/wayland/src/protocol/value/decode.zig:76tiny.wayland.protocol.value.Decoder.optionalObject[method] atlib/wayland/src/protocol/value/decode.zig:80tiny.wayland.protocol.value.Decoder.optionalString[method] atlib/wayland/src/protocol/value/decode.zig:65lib.wayland.src.protocol.value.test.test_all_Wayland_argument_forms_round_trip_with_independent_descriptors[function] — test source atlib/wayland/src/protocol/value/test.zig:15in nearest public ownerlib.wayland.src.protocol.value.testtiny.wayland.protocol.value.validate.message[function] atlib/wayland/src/protocol/value/validate.zig:4
Complete caller list for protocol.value.Encoder.deinit
7 direct callers.
lib.wayland.src.protocol.value.encode.test_encoder_accounts_for_schema_descriptors_before_exposing_a_message[function] — test source atlib/wayland/src/protocol/value/encode.zig:297in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_acquires_both_regions_before_use[function] — test source atlib/wayland/src/protocol/value/encode.zig:343in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_distinguishes_null_and_empty_strings[function] — test source atlib/wayland/src/protocol/value/encode.zig:263in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_max_plus_one_preserves_borrowed_descriptors[function] — test source atlib/wayland/src/protocol/value/encode.zig:395in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_max_plus_one_preserves_payload_and_saturates_status[function] — test source atlib/wayland/src/protocol/value/encode.zig:370in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_rejects_invalid_protocol_strings_and_oversized_payloads[function] — test source atlib/wayland/src/protocol/value/encode.zig:288in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.validate.test_generic_validation_follows_expanded_scanner_signatures[function] — test source atlib/wayland/src/protocol/value/validate.zig:60in nearest public ownertiny.wayland.protocol.value.validate
Complete caller list for protocol.value.Encoder.init
7 direct callers.
lib.wayland.src.protocol.value.encode.test_encoder_accounts_for_schema_descriptors_before_exposing_a_message[function] — test source atlib/wayland/src/protocol/value/encode.zig:297in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_acquires_both_regions_before_use[function] — test source atlib/wayland/src/protocol/value/encode.zig:343in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_distinguishes_null_and_empty_strings[function] — test source atlib/wayland/src/protocol/value/encode.zig:263in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_max_plus_one_preserves_borrowed_descriptors[function] — test source atlib/wayland/src/protocol/value/encode.zig:395in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_max_plus_one_preserves_payload_and_saturates_status[function] — test source atlib/wayland/src/protocol/value/encode.zig:370in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.encode.test_encoder_rejects_invalid_protocol_strings_and_oversized_payloads[function] — test source atlib/wayland/src/protocol/value/encode.zig:288in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.validate.test_generic_validation_follows_expanded_scanner_signatures[function] — test source atlib/wayland/src/protocol/value/validate.zig:60in nearest public ownertiny.wayland.protocol.value.validate
Complete caller list for protocol.value.Encoder.unsigned
8 direct callers.
tiny.wayland.protocol.value.Encoder.dynamicNewId[method] atlib/wayland/src/protocol/value/encode.zig:151tiny.wayland.protocol.value.Encoder.newId[method] atlib/wayland/src/protocol/value/encode.zig:147tiny.wayland.protocol.value.Encoder.object[method] atlib/wayland/src/protocol/value/encode.zig:139tiny.wayland.protocol.value.Encoder.optionalObject[method] atlib/wayland/src/protocol/value/encode.zig:143tiny.wayland.protocol.value.Encoder.optionalString[method] atlib/wayland/src/protocol/value/encode.zig:134lib.wayland.src.protocol.value.encode.test_encoder_max_plus_one_preserves_payload_and_saturates_status[function] — test source atlib/wayland/src/protocol/value/encode.zig:370in nearest public ownerlib.wayland.src.protocol.value.encodelib.wayland.src.protocol.value.test.test_all_Wayland_argument_forms_round_trip_with_independent_descriptors[function] — test source atlib/wayland/src/protocol/value/test.zig:15in nearest public ownerlib.wayland.src.protocol.value.testlib.wayland.src.protocol.value.validate.test_generic_validation_follows_expanded_scanner_signatures[function] — test source atlib/wayland/src/protocol/value/validate.zig:60in nearest public ownertiny.wayland.protocol.value.validate
Audit
| Definitions | 53 |
|---|---|
| Public names | 53 |
| Members | 48 |
| Version | 26.7.0 |
| Revision | daab053ee433 |