Module: GDAL::InternalHelpers::ClassMethods

Defined in:
lib/gdal/internal_helpers.rb

Instance Method Summary collapse

Instance Method Details

#_buffer_from_data_type(data_type, size = nil) ⇒ FFI::Buffer

Parameters:

Returns:

  • (FFI::Buffer)


55
56
57
58
59
60
61
62
63
# File 'lib/gdal/internal_helpers.rb', line 55

def _buffer_from_data_type(data_type, size = nil)
  pointer_type = _gdal_data_type_to_ffi(data_type)

  if size
    FFI::Buffer.alloc_inout(pointer_type, size)
  else
    FFI::Buffer.alloc_inout(pointer_type)
  end
end

#_cpl_read_and_free_string {|FFI::MemoryPointer| ... } ⇒ String

Convenience function for allocating a pointer to a string (**char), yielding the pointer so it can written to (i.e. passed to a GDAL/OGR function to be written to), then reads the string out of the buffer, then calls FFI::CPL::VSI.VSIFree (which is an alias for FFI::CPL::Conv.CPLFree).

Yields:

  • (FFI::MemoryPointer)

Returns:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/gdal/internal_helpers.rb', line 120

def _cpl_read_and_free_string
  result_ptr_ptr = GDAL._pointer_pointer(:string)
  result_ptr_ptr.autorelease = false

  yield result_ptr_ptr

  result = if result_ptr_ptr.null?
             ""
           else
             GDAL._read_pointer_pointer_safely(result_ptr_ptr, :string)
           end

  FFI::CPL::VSI.VSIFree(result_ptr_ptr)

  result
end

#_gdal_access_flag(char) ⇒ Symbol

Returns :GF_Read if ‘r’ or :GF_Write if ‘w’.

Parameters:

  • char (String)

    ‘r’ or ‘w’

Returns:

  • (Symbol)

    :GF_Read if ‘r’ or :GF_Write if ‘w’.

Raises:



245
246
247
248
249
250
251
# File 'lib/gdal/internal_helpers.rb', line 245

def _gdal_access_flag(char)
  case char
  when "r" then :GF_Read
  when "w" then :GF_Write
  else raise GDAL::InvalidAccessFlag, "Invalid access flag: #{char}"
  end
end

#_gdal_data_type_to_ffi(data_type) ⇒ Symbol

Maps GDAL DataTypes to FFI types.

Parameters:

Returns:

  • (Symbol)


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/gdal/internal_helpers.rb', line 141

def _gdal_data_type_to_ffi(data_type)
  case data_type
  when :GDT_Byte                    then :uchar
  when :GDT_Int8                    then :int8
  when :GDT_UInt16                  then :uint16
  when :GDT_Int16, :GDT_CInt16      then :int16
  when :GDT_UInt32                  then :uint32
  when :GDT_Int32, :GDT_CInt32      then :int32
  when :GDT_UInt64                  then :uint64
  when :GDT_Int64                   then :int64
  when :GDT_Float32, :GDT_CFloat32  then :float
  when :GDT_Float64, :GDT_CFloat64  then :double
  else
    raise GDAL::InvalidDataType, "Unknown data type: #{data_type}"
  end
end

#_gdal_data_type_to_narray(data_type) ⇒ Symbol

Maps GDAL DataTypes to NArray types.

Parameters:

Returns:

  • (Symbol)


162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/gdal/internal_helpers.rb', line 162

def _gdal_data_type_to_narray(data_type)
  case data_type
  when :GDT_Byte                                then :byte
  when :GDT_Int16                               then :sint
  when :GDT_UInt16, :GDT_Int32, :GDT_UInt32     then :int
  when :GDT_Float32                             then :float
  when :GDT_Float64                             then :dfloat
  when :GDT_CInt16, :GDT_CInt32                 then :scomplex
  when :GDT_CFloat32                            then :complex
  when :GDT_CFloat64                            then :dcomplex
  else
    raise GDAL::InvalidDataType, "Unknown data type: #{data_type}"
  end
end

#_gdal_data_type_to_narray_type_constant(data_type) ⇒ Symbol

Maps GDAL DataTypes to NArray type constants.

Parameters:

Returns:

  • (Symbol)


181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/gdal/internal_helpers.rb', line 181

def _gdal_data_type_to_narray_type_constant(data_type)
  case data_type
  when :GDT_Byte                            then NArray::BYTE
  when :GDT_Int16                           then NArray::SINT
  when :GDT_UInt16, :GDT_Int32, :GDT_UInt32 then NArray::INT
  when :GDT_Float32                         then NArray::FLOAT
  when :GDT_Float64                         then NArray::DFLOAT
  when :GDT_CInt16, :GDT_CInt32             then NArray::SCOMPLEX
  when :GDT_CFloat32                        then NArray::COMPLEX
  when :GDT_CFloat64                        then NArray::DCOMPLEX
  else
    raise GDAL::InvalidDataType, "Unknown data type: #{data_type}"
  end
end

#_narray_from_data_type(data_type, *narray_args) ⇒ NArray

Parameters:

Returns:



68
69
70
71
72
73
# File 'lib/gdal/internal_helpers.rb', line 68

def _narray_from_data_type(data_type, *narray_args)
  init_meth = _gdal_data_type_to_narray(data_type)
  narray_args = 0 if narray_args.empty?

  NArray.send(init_meth, *narray_args)
end

#_pointer(klass, variable, warn_on_nil: true, autorelease: true) ⇒ FFI::Pointer?

Internal factory method for returning a pointer from variable, which could be either of klass class or a type of FFI::Pointer.

Parameters:

  • klass (Class)
  • variable (Object)
  • warn_on_nil (Boolean) (defaults to: true)

    If true, print out warning that the method couldn’t do what it’s supposed to do.

  • autorelease (Boolean) (defaults to: true)

    Pass this on to the pointer.

Returns:

  • (FFI::Pointer, nil)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/gdal/internal_helpers.rb', line 20

def _pointer(klass, variable, warn_on_nil: true, autorelease: true)
  case variable
  when klass
    variable.c_pointer.autorelease = autorelease
    variable.c_pointer
  when FFI::MemoryPointer
    variable.autorelease = autorelease
    variable
  when FFI::Pointer
    # This is a C-allocated pointer and needs to be freed using a C method,
    # and thus shouldn't be autorelease-freed.
    variable
  else
    if warn_on_nil && Logger.logging_enabled
      Logger.logger.debug "<#{name}._pointer> #{variable.inspect} is not a valid #{klass} or FFI::Pointer."
      Logger.logger.debug "<#{name}._pointer> Called at:"
      caller(1, 2).each { |line| Logger.logger.debug "<#{name}._pointer>\t#{line}" }
    end

    nil
  end
end

#_pointer_from_data_type(data_type, size = nil) ⇒ FFI::MemoryPointer

Parameters:

Returns:

  • (FFI::MemoryPointer)


46
47
48
49
50
# File 'lib/gdal/internal_helpers.rb', line 46

def _pointer_from_data_type(data_type, size = nil)
  pointer_type = _gdal_data_type_to_ffi(data_type)

  size ? FFI::MemoryPointer.new(pointer_type, size) : FFI::MemoryPointer.new(pointer_type)
end

#_pointer_pointer(type) ⇒ FFI::MemoryPointer

Returns Pointer to a pointer.

Parameters:

  • type (Symbol)

    FFI type of pointer to make a pointer to.

Returns:

  • (FFI::MemoryPointer)

    Pointer to a pointer.



97
98
99
100
101
102
103
# File 'lib/gdal/internal_helpers.rb', line 97

def _pointer_pointer(type)
  pointer = FFI::MemoryPointer.new(type)
  pointer_ptr = FFI::MemoryPointer.new(:pointer)
  pointer_ptr.write_pointer(pointer)

  pointer_ptr
end

#_read_pointer(pointer, data_type, length = 1) ⇒ Number+

Helper method for reading an FFI pointer based on the GDAL DataType of the pointer.

Parameters:

  • pointer (FFI::Pointer)

    The pointer to read from.

  • data_type (FFI::GDAL::GDAL::DataType)

    The GDAL data type that determines what FFI type to use when reading.

  • length (Integer) (defaults to: 1)

    The amount of data to read from the pointer. If > 1, the “read_array_of_” method will be called.

Returns:

  • (Number, Array<Number>)


205
206
207
208
209
210
211
# File 'lib/gdal/internal_helpers.rb', line 205

def _read_pointer(pointer, data_type, length = 1)
  if length == 1
    pointer.send(:"read_#{_gdal_data_type_to_ffi(data_type)}")
  else
    pointer.send(:"read_array_of_#{_gdal_data_type_to_ffi(data_type)}", length)
  end
end

#_read_pointer_pointer_safely(pointer_ptr, type) ⇒ String?

Returns:



106
107
108
109
110
# File 'lib/gdal/internal_helpers.rb', line 106

def _read_pointer_pointer_safely(pointer_ptr, type)
  return if pointer_ptr.read_pointer.null?

  pointer_ptr.read_pointer.send(:"read_#{type}")
end

#_string_array_to_pointer(strings) ⇒ FFI::MemoryPointer

Takes an array of strings (or things that should be converted to strings) and creates a char**.

Parameters:

Returns:

  • (FFI::MemoryPointer)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/gdal/internal_helpers.rb', line 80

def _string_array_to_pointer(strings)
  string_pointers = strings.map { |string| FFI::MemoryPointer.from_string(string.to_s) }
  string_pointers << nil
  array_pointer = FFI::MemoryPointer.new(:pointer, strings.size + 1)
  i = 0

  # fast-ruby says while is faster than each_with_index
  while i < string_pointers.length
    array_pointer[i].put_pointer(0, string_pointers[i])
    i += 1
  end

  array_pointer
end

#_supported?(function_name) ⇒ Boolean

Check to see if the function is supported in the version of GDAL that we’re using.

TODO: Should the #respond_to? check all FFI::GDAL::* classes? What about

OGR?

Parameters:

  • function_name (Symbol)

Returns:

  • (Boolean)


237
238
239
240
# File 'lib/gdal/internal_helpers.rb', line 237

def _supported?(function_name)
  !FFI::GDAL.unsupported_gdal_functions.include?(function_name) &&
    FFI::GDAL::GDAL.respond_to?(function_name)
end

#_write_pointer(pointer, data_type, data) ⇒ Object

Helper method for writing data to an FFI pointer based on the GDAL DataType of the pointer.

Parameters:

  • pointer (FFI::Pointer)

    The pointer to write to.

  • data_type (FFI::GDAL::GDAL::DataType)

    The GDAL data type that determines what FFI type to use when writing.

  • data (Integer)

    The data to write to the pointer. If it’s an Array with size > 1, the “write_array_of_” method will be called.



221
222
223
224
225
226
227
228
# File 'lib/gdal/internal_helpers.rb', line 221

def _write_pointer(pointer, data_type, data)
  if data.is_a?(Array) && data.size > 1
    pointer.send(:"write_array_of_#{_gdal_data_type_to_ffi(data_type)}", data)
  else
    data = data.first if data.is_a?(Array)
    pointer.send(:"write_#{_gdal_data_type_to_ffi(data_type)}", data)
  end
end