class GObject::GValue

def self.alloc

Returns:
  • (GValue) - a new gvalue set to 0
def self.alloc
  # allocate memory
  memory = FFI::MemoryPointer.new GValue
  # make this alloc autorelease ... we mustn't release in
  # GValue::release, since we are used to wrap GValue pointers
  # made by other people
  pointer = FFI::Pointer.new GValue, memory
  # ... and wrap in a GValue
  GValue.new pointer
end

def self.from_nick(gtype, value)

convert an enum value (str/symb/int) into an int ready for libvips
def self.from_nick(gtype, value)
  value = value.to_s if value.is_a? Symbol
  if value.is_a? String
    # libvips expects "-" as a separator in enum names, but "_" is more
    # convenient for ruby, eg. :b_w
    value = Vips.vips_enum_from_nick "ruby-vips", gtype, value.tr("_", "-")
    if value == -1
      raise Vips::Error
    end
  end
  value
end

def self.release ptr

def self.release ptr
  # GLib::logger.debug("GObject::GValue::release") {"ptr = #{ptr}"}
  ::GObject.g_value_unset ptr
end

def self.to_nick(gtype, enum_value)

convert an int enum back into a symbol
def self.to_nick(gtype, enum_value)
  enum_name = Vips.vips_enum_nick gtype, enum_value
  if enum_name.nil?
    raise Vips::Error
  end
  enum_name.to_sym
end

def get

Returns:
  • (Any) - the value held by the GValue
def get
  gtype = self[:gtype]
  fundamental = ::GObject.g_type_fundamental gtype
  result = nil
  case gtype
  when GBOOL_TYPE
    result = ::GObject.g_value_get_boolean(self) != 0
  when GINT_TYPE
    result = ::GObject.g_value_get_int self
  when GUINT64_TYPE
    result = ::GObject.g_value_get_uint64 self
  when GDOUBLE_TYPE
    result = ::GObject.g_value_get_double self
  when GSTR_TYPE
    result = ::GObject.g_value_get_string self
  when Vips::REFSTR_TYPE
    len = Vips::SizeStruct.new
    result = ::Vips.vips_value_get_ref_string self, len
  when Vips::ARRAY_INT_TYPE
    len = Vips::IntStruct.new
    array = Vips.vips_value_get_array_int self, len
    result = array.get_array_of_int32 0, len[:value]
  when Vips::ARRAY_DOUBLE_TYPE
    len = Vips::IntStruct.new
    array = Vips.vips_value_get_array_double self, len
    result = array.get_array_of_double 0, len[:value]
  when Vips::ARRAY_IMAGE_TYPE
    len = Vips::IntStruct.new
    array = Vips.vips_value_get_array_image self, len
    result = array.get_array_of_pointer 0, len[:value]
    result.map! do |pointer|
      ::GObject.g_object_ref pointer
      Vips::Image.new pointer
    end
  when Vips::BLOB_TYPE
    len = Vips::SizeStruct.new
    array = Vips.vips_value_get_blob self, len
    result = array.get_bytes 0, len[:value]
  else
    case fundamental
    when GFLAGS_TYPE
      result = ::GObject.g_value_get_flags self
    when GENUM_TYPE
      enum_value = ::GObject.g_value_get_enum(self)
      result = GValue.to_nick self[:gtype], enum_value
    when GOBJECT_TYPE
      obj = ::GObject.g_value_get_object self
      # g_value_get_object() does not add a ref ... we need to add
      # one to match the unref in gobject release
      ::GObject.g_object_ref obj
      result = Vips::Image.new obj
    else
      raise Vips::Error, "unimplemented gtype for get: " \
        "#{::GObject.g_type_name gtype} (#{gtype})"
    end
  end
  # GLib::logger.debug("GObject::GValue.get") {
  #     "result = #{result.inspect[0..50]}"
  # }
  result
end

def init gtype

Parameters:
  • gtype (GType) -- the type of thing this GValue can hold.
def init gtype
  ::GObject.g_value_init self, gtype
end

def set value

Parameters:
  • value (Any) -- The value to set
def set value
  # GLib::logger.debug("GObject::GValue.set") {
  #     "value = #{value.inspect[0..50]}"
  # }
  gtype = self[:gtype]
  fundamental = ::GObject.g_type_fundamental gtype
  case gtype
  when GBOOL_TYPE
    ::GObject.g_value_set_boolean self, (value ? 1 : 0)
  when GINT_TYPE
    ::GObject.g_value_set_int self, value
  when GUINT64_TYPE
    ::GObject.g_value_set_uint64 self, value
  when GDOUBLE_TYPE
    ::GObject.g_value_set_double self, value
  when GSTR_TYPE
    ::GObject.g_value_set_string self, value
  when Vips::REFSTR_TYPE
    ::Vips.vips_value_set_ref_string self, value
  when Vips::ARRAY_INT_TYPE
    value = [value] unless value.is_a? Array
    Vips.vips_value_set_array_int self, nil, value.length
    ptr = Vips.vips_value_get_array_int self, nil
    ptr.write_array_of_int32 value
  when Vips::ARRAY_DOUBLE_TYPE
    value = [value] unless value.is_a? Array
    # this will allocate an array in the gvalue
    Vips.vips_value_set_array_double self, nil, value.length
    # pull the array out and fill it
    ptr = Vips.vips_value_get_array_double self, nil
    ptr.write_array_of_double value
  when Vips::ARRAY_IMAGE_TYPE
    value = [value] unless value.is_a? Array
    Vips.vips_value_set_array_image self, value.length
    ptr = Vips.vips_value_get_array_image self, nil
    ptr.write_array_of_pointer value
    # the gvalue needs a ref on each of the images
    value.each { |image| ::GObject.g_object_ref image }
  when Vips::BLOB_TYPE
    len = value.bytesize
    ptr = GLib.g_malloc len
    Vips.vips_value_set_blob self, GLib::G_FREE, ptr, len
    ptr.write_bytes value
  else
    case fundamental
    when GFLAGS_TYPE
      ::GObject.g_value_set_flags self, value
    when GENUM_TYPE
      enum_value = GValue.from_nick(self[:gtype], value)
      ::GObject.g_value_set_enum self, enum_value
    when GOBJECT_TYPE
      ::GObject.g_value_set_object self, value
    else
      raise Vips::Error, "unimplemented gtype for set: " \
        "#{::GObject.g_type_name gtype} (#{gtype})"
    end
  end
end

def unset

handy if you need to drop a reference explicitly for some reason.
This happens automatically when a GValue is GCed, but this method can be

Clear the thing held by a GValue.
def unset
  ::GObject.g_value_unset self
end