Sha256: a2f58a6cc81409c8c8950503d67ec48bd9c02607d5605e2ef320c0c9da850c10
Contents?: true
Size: 1.98 KB
Versions: 3
Compression:
Stored size: 1.98 KB
Contents
# frozen_string_literal: true module GirFFI # Represents a null-terminated array. class ZeroTerminated include Enumerable attr_reader :element_type def initialize(elm_t, ptr) @element_type = elm_t @ptr = ptr end def to_ptr @ptr end def self.from(type, arg) new type, InPointer.from_array(type, arg) end def self.wrap(type, arg) new type, arg end def each return if @ptr.null? offset = 0 while (val = read_value(offset)) offset += ffi_type_size yield wrap_value(val) end end def ==(other) to_a == other.to_a end private def read_value(offset) val = fetch_value(offset) val unless null_value? val end def getter_method @getter_method ||= "get_#{ffi_type}" end def fetch_value(offset) case ffi_type when Module ffi_type.get_value_from_pointer(@ptr, offset) when Symbol @ptr.send(getter_method, offset) else raise NotImplementedError end end def wrap_value(val) case element_type when Array element_type.last.wrap val when Class element_type.wrap val else val end end def ffi_type @ffi_type ||= TypeMap.type_specification_to_ffi_type element_type end def ffi_type_size @ffi_type_size ||= FFI.type_size(ffi_type) end def null_check_strategy @null_check_strategy ||= if ffi_type == :pointer :pointer elsif ffi_type.is_a? Symbol :numeric elsif ffi_type < GirFFI::ClassBase # rubocop:disable Lint/DuplicateBranch :pointer elsif ffi_type.singleton_class.include? GirFFI::EnumBase :enum end end def null_value?(val) case null_check_strategy when :pointer val.null? when :enum ffi_type.to_native(val, nil) == 0 else val == 0 end end end end
Version data entries
3 entries across 3 versions & 1 rubygems
Version | Path |
---|---|
gir_ffi-0.17.0 | lib/gir_ffi/zero_terminated.rb |
gir_ffi-0.16.1 | lib/gir_ffi/zero_terminated.rb |
gir_ffi-0.16.0 | lib/gir_ffi/zero_terminated.rb |