Module: Cobhan
- Includes:
- FFI::Library
- Defined in:
- lib/cobhan.rb,
lib/cobhan/version.rb
Overview
Cobhan module includes helper functions to manage unsafe data marshaling.
Constant Summary collapse
- UnsupportedPlatformError =
Class.new(StandardError)
- EXTS =
{ 'linux' => 'so', 'darwin' => 'dylib', 'windows' => 'dll' }.freeze
- CPU_ARCHS =
{ 'x86_64' => 'x64', 'aarch64' => 'arm64' }.freeze
- SIZEOF_INT32 =
32 / 8
- BUFFER_HEADER_SIZE =
SIZEOF_INT32 * 2
- VERSION =
'0.2.2'
Instance Method Summary collapse
- #allocate_cbuffer(size) ⇒ Object
- #buffer_to_int(buffer_ptr) ⇒ Object
- #cbuffer_to_string(buffer) ⇒ Object
- #int_to_buffer(number) ⇒ Object
- #library_file_name(name) ⇒ Object
- #load_library(lib_root_path, name, functions) ⇒ Object
- #string_to_cbuffer(input) ⇒ Object
- #temp_to_string(buffer, length) ⇒ Object
Instance Method Details
#allocate_cbuffer(size) ⇒ Object
68 69 70 71 72 73 |
# File 'lib/cobhan.rb', line 68 def allocate_cbuffer(size) buffer_ptr = FFI::MemoryPointer.new(1, BUFFER_HEADER_SIZE + size, false) buffer_ptr.put_int32(0, size) buffer_ptr.put_int32(SIZEOF_INT32, 0) # Reserved - must be zero buffer_ptr end |
#buffer_to_int(buffer_ptr) ⇒ Object
81 82 83 |
# File 'lib/cobhan.rb', line 81 def buffer_to_int(buffer_ptr) buffer_ptr.get_int64(0) end |
#cbuffer_to_string(buffer) ⇒ Object
50 51 52 53 54 55 56 57 |
# File 'lib/cobhan.rb', line 50 def cbuffer_to_string(buffer) length = buffer.get_int32(0) if length >= 0 buffer.get_bytes(BUFFER_HEADER_SIZE, length) else temp_to_string(buffer, length) end.force_encoding(Encoding::UTF_8) end |
#int_to_buffer(number) ⇒ Object
75 76 77 78 79 |
# File 'lib/cobhan.rb', line 75 def int_to_buffer(number) buffer_ptr = FFI::MemoryPointer.new(1, SIZEOF_INT32 * 2, false) buffer_ptr.put_int64(0, number) buffer_ptr end |
#library_file_name(name) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/cobhan.rb', line 19 def library_file_name(name) ext = EXTS[FFI::Platform::OS] raise UnsupportedPlatformError, "Unsupported OS: #{FFI::Platform::OS}" unless ext cpu_arch = CPU_ARCHS[FFI::Platform::ARCH] raise UnsupportedPlatformError, "Unsupported CPU: #{FFI::Platform::ARCH}" unless cpu_arch libc_suffix = RbConfig::CONFIG['host_os'] == 'linux-musl' ? '-musl' : '' "#{name}-#{cpu_arch}#{libc_suffix}.#{ext}" end |
#load_library(lib_root_path, name, functions) ⇒ Object
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/cobhan.rb', line 31 def load_library(lib_root_path, name, functions) # To load other libs that depend on relative paths, chdir to lib path dir. Dir.chdir(lib_root_path) do ffi_lib File.join(lib_root_path, library_file_name(name)) end functions.each do |function| attach_function(*function) end end |
#string_to_cbuffer(input) ⇒ Object
42 43 44 45 46 47 48 |
# File 'lib/cobhan.rb', line 42 def string_to_cbuffer(input) buffer_ptr = FFI::MemoryPointer.new(1, BUFFER_HEADER_SIZE + input.bytesize, false) buffer_ptr.put_int32(0, input.bytesize) buffer_ptr.put_int32(SIZEOF_INT32, 0) # Reserved - must be zero buffer_ptr.put_bytes(BUFFER_HEADER_SIZE, input) buffer_ptr end |
#temp_to_string(buffer, length) ⇒ Object
59 60 61 62 63 64 65 66 |
# File 'lib/cobhan.rb', line 59 def temp_to_string(buffer, length) length = 0 - length filename = buffer.get_bytes(BUFFER_HEADER_SIZE, length) # Read file with name in payload, and replace payload bytes = File.binread(filename) File.delete(filename) bytes end |