Module: Leptris::XML::CStringArray
- Defined in:
- lib/leptris/xml/c_string_array.rb
Overview
Adapter for libleptris's NULL-terminated char** wire format. Both directions of the conversion live here so the pointer arithmetic has one home (previously c14n built the array by hand and SAX walked it by hand).
Class Method Summary collapse
-
.to_c(strings) ⇒ Object
Ruby strings -> NULL-terminated char**.
-
.to_ruby(ptr) ⇒ Object
NULL-terminated char** -> Ruby strings.
Class Method Details
.to_c(strings) ⇒ Object
Ruby strings -> NULL-terminated char**. Returns [buffer, anchors]; the caller must keep both referenced for the duration of the FFI call (e.g. via local variables).
11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/leptris/xml/c_string_array.rb', line 11 def self.to_c(strings) strs = Array(strings).map(&:to_s) return [nil, nil] if strs.empty? ptr_size = ::FFI::type_size(:pointer) buffer = ::FFI::MemoryPointer.new(:pointer, strs.size + 1) anchors = strs.map { |s| ::FFI::MemoryPointer.from_string(s) } anchors.each_with_index { |p, i| buffer.put_pointer(i * ptr_size, p) } buffer.put_pointer(strs.size * ptr_size, nil) [buffer, anchors] end |
.to_ruby(ptr) ⇒ Object
NULL-terminated char** -> Ruby strings. Stops at the first NULL entry. Returns [] for a NULL pointer.
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/leptris/xml/c_string_array.rb', line 25 def self.to_ruby(ptr) return [] if ptr.nil? || ptr.null? ptr_size = ::FFI::type_size(:pointer) result = [] offset = 0 while (entry = ptr.get_pointer(offset)) && !entry.null? result << entry.read_string.force_encoding(Encoding::UTF_8) offset += ptr_size end result end |