Less magic in type class construction.

This commit is contained in:
Vidar Hokstad 2023-12-28 17:17:10 +00:00
parent d28ebf0b3c
commit cfff274350

View file

@ -1,54 +1,50 @@
# This module is used for encoding Ruby Objects to binary # This module is used for encoding Ruby Objects to binary
# data. The types Int8, Int16, etc. are data-types defined # data. The types Int8, Int16, etc. are data-types defined
# in the X11 protocol. We wrap each data-type in a lambda expression # in the X11 protocol.
# which gets evaluated when a packet is created.
module X11 module X11
module Type module Type
def self.define(type, directive, bytesize) class BaseType
eval %{ @directive = nil
class X11::Type::#{type} @bytesize = nil
def self.pack(x)
[x].pack(\"#{directive}\")
end
def self.unpack(x) def self.config(d,b) = (@directive, @bytesize = d,b)
x.unpack(\"#{directive}\").first
end
def self.size def self.pack(x)
#{bytesize} if x.is_a?(Symbol)
end if (t = X11::Form.const_get(x)) && t.is_a?(Numeric)
x = t
def self.from_packet(sock)
r = sock.read(size)
r ? unpack(r) : nil
end end
end end
} [x].pack(@directive)
rescue TypeError => e
raise "Expected #{self.name}, got #{x.class} (value: #{x})"
end
def self.unpack(x) = x.nil? ? nil : x.unpack1(@directive)
def self.size = @bytesize
def self.from_packet(sock) = unpack(sock.read(size))
end end
# Primitive Types # Primitive Types
define "Int8", "c", 1 class Int8 < BaseType; config("c",1); end
define "Int16", "s", 2 class Int16 < BaseType; config("s",2); end
define "Int32", "l", 4 class Int32 < BaseType; config("l",4); end
define "Uint8", "C", 1 class Uint8 < BaseType; config("C",1); end
define "Uint16", "S", 2 class Uint16 < BaseType; config("S",2); end
define "Uint32", "L", 4 class Uint32 < BaseType; config("L",4); end
define "Message", "c*", 20
class Message class Message
def self.pack(x) = x.b def self.pack(x) = x.b
def self.unpack(x) = x.b def self.unpack(x) = x.b
def self.size = 20 def self.size = 20
def self.from_packet(sock) = sock.read(2).b def self.from_packet(sock) = sock.read(2).b
end end
class String8 class String8
def self.pack(x) def self.pack(x)
x.force_encoding("ASCII-8BIT") + "\x00"*(-x.length & 3) x.b + "\x00"*(-x.length & 3)
end end
def self.unpack(socket, size) def self.unpack(socket, size)