Module: ElfUtils::Types::SLEB128 Private

Extended by:
CTypes::Type
Defined in:
lib/elf_utils/types/sleb128.rb

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

Class Method Summary collapse

Class Method Details

.fixed_size?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)


16
17
18
# File 'lib/elf_utils/types/sleb128.rb', line 16

def self.fixed_size?
  false
end

.pack(value, endian: default_endian, validate: true) ⇒ 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.

provide a method for packing the ruby value into the binary representation



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

def self.pack(value, endian: default_endian, validate: true)
  return "\0" if value == 0
  buf = +""
  done = false
  until done
    byte = (value & 0x7f)
    value >>= 7
    signed = byte & 0x40 != 0

    if (value == 0 && !signed) || (value == -1 && signed)
      done = true
    else
      byte |= 0x80
    end

    buf << byte
  end

  buf
end

.sizeObject

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.



20
21
22
# File 'lib/elf_utils/types/sleb128.rb', line 20

def self.size
  @size
end

.unpack_one(buf, endian: default_endian) ⇒ 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.

provide a method for unpacking an instance of this type from a String, and returning both the unpacked value, and any unused input

Raises:

  • (TerminatorNotFoundError)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/elf_utils/types/sleb128.rb', line 48

def self.unpack_one(buf, endian: default_endian)
  value = 0
  shift = 0
  len = 0
  terminated, sign_extend = buf.each_byte do |b|
    len += 1
    value |= ((b & 0x7f) << shift)
    shift += 7
    if (b & 0x80) == 0
      break [true, b & 0x40 != 0]
    end
  end
  raise TerminatorNotFoundError unless terminated

  value |= (~0 << shift) if sign_extend

  [value, buf.byteslice(len..)]
end