Class: CTypes::Int

Inherits:
Object
  • Object
show all
Includes:
Type
Defined in:
lib/ctypes/int.rb

Overview

Handles packing and unpacking of integer types of various lengths and signed-ness. The most common integer sizes have been declared as constants:

or their respective helpers in Helpers.

Instance Attribute Summary collapse

Attributes included from Type

#dry_type, #endian

Instance Method Summary collapse

Methods included from Type

#default_endian, #default_value, #fixed_size?, #pread, #read, #unpack, #unpack_all, #with_endian, #without_endian

Constructor Details

#initialize(bits:, signed:, format:, desc:) ⇒ Int

initialize an CTypes::Int type

Parameters:

  • bits (Integer)

    number of bits in the integer

  • signed (Boolean)

    set to true if integer is signed

  • format (String)

    Array#pack format for integer

  • desc (String)

    human-readable description of type



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ctypes/int.rb', line 24

def initialize(bits:, signed:, format:, desc:)
  type = Dry::Types["integer"].default(0)
  @signed = !!signed
  if @signed
    @min = 0 - (1 << (bits - 1))
    @max = 1 << (bits - 1) - 1
  else
    @min = 0
    @max = (1 << bits) - 1
  end
  @dry_type = type.constrained(gteq: @min, lteq: @max)
  @size = bits / 8
  if @size > 1
    @format_big = "#{format}>"
    @format_little = "#{format}<"
  else
    @format_big = @format_little = format.to_s
  end
  @fmt = (@size > 1) ? {big: "#{format}>", little: "#{format}<"} :
    {big: format.to_s, little: format.to_s}
  @desc = desc
end

Instance Attribute Details

#maxObject (readonly)

Returns the value of attribute max.



46
47
48
# File 'lib/ctypes/int.rb', line 46

def max
  @max
end

#minObject (readonly)

Returns the value of attribute min.



46
47
48
# File 'lib/ctypes/int.rb', line 46

def min
  @min
end

#sizeObject (readonly)

Returns the value of attribute size.



46
47
48
# File 'lib/ctypes/int.rb', line 46

def size
  @size
end

Instance Method Details

#export_type(q) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



120
121
122
123
# File 'lib/ctypes/int.rb', line 120

def export_type(q) # :nodoc:
  q << @desc
  q << ".with_endian(%p)" % [@endian] if @endian
end

#greedy?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


100
101
102
# File 'lib/ctypes/int.rb', line 100

def greedy?
  false
end

#pack(value, endian: default_endian, validate: true) ⇒ String

convert an Integer into a String containing the binary representation of that number for the given type.

Examples:

pack a uint32_t using the native endian

CTypes::UInt32.pack(0x12345678) # => "\x78\x56\x34\x12"

pack a big endian uint32_t

CTypes::UInt32.pack(endian: :big) # => "\x12\x34\x56\x78"

pack a fixed-endian (big) uint32_t

t = UInt32.with_endian(:big)
t.pack(0x12345678) # => "\x12\x34\x56\x78"

Parameters:

  • value (Integer)

    number to pack

  • endian (Symbol) (defaults to: default_endian)

    byte order

  • validate (Boolean) (defaults to: true)

    set to false to disable bounds checking

Returns:

  • (String)

    binary encoding for value

See Also:



67
68
69
70
71
# File 'lib/ctypes/int.rb', line 67

def pack(value, endian: default_endian, validate: true)
  value = (value.nil? ? @dry_type[] : @dry_type[value]) if validate
  endian ||= default_endian
  [value].pack(@fmt[endian])
end

#pretty_print(q) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



110
111
112
113
114
115
116
# File 'lib/ctypes/int.rb', line 110

def pretty_print(q) # :nodoc:
  if @endian
    q.text(@desc + ".with_endian(%p)" % @endian)
  else
    q.text(@desc)
  end
end

#signed?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


105
106
107
# File 'lib/ctypes/int.rb', line 105

def signed?
  @signed
end

#type_nameObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



126
127
128
# File 'lib/ctypes/int.rb', line 126

def type_name
  "#{@desc}_t"
end

#unpack_one(buf, endian: default_endian) ⇒ Integer, String

decode an Integer from the byte String provided, returning both the Integer and any unused bytes in the String

Examples:

pack a uint32_t using the native endian

CTypes::UInt32.pack(0x12345678) # => "\x78\x56\x34\x12"

pack a big endian uint32_t

CTypes::UInt32.pack(endian: :big) # => "\x12\x34\x56\x78"

pack a fixed-endian (big) uint32_t

t = UInt32.with_endian(:big)
t.pack(0x12345678) # => "\x12\x34\x56\x78"

Parameters:

  • buf (String)

    bytes to be unpacked

  • endian (Symbol) (defaults to: default_endian)

    endian of data within buf

Returns:

  • (Integer, String)

    decoded Integer, and remaining bytes

See Also:



92
93
94
95
96
97
# File 'lib/ctypes/int.rb', line 92

def unpack_one(buf, endian: default_endian)
  endian ||= default_endian # override nil
  value = buf.unpack1(@fmt[endian]) or
    raise missing_bytes_error(input: buf, need: @size)
  [value, buf.byteslice(@size..)]
end