/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdlib.h>
#include <string.h>

#include "gudevdevice.h"
#include "gudevprivate.h"

/**
 * SECTION:gudevdevice
 * @short_description: Get information about a device
 *
 * The #GUdevDevice class is used to get information about a specific
 * device. Note that you cannot instantiate a #GUdevDevice object
 * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
 * objects.
 *
 * To get basic information about a device, use
 * g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
 * g_udev_device_get_name(), g_udev_device_get_number(),
 * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
 * g_udev_device_get_action(), g_udev_device_get_seqnum(),
 * g_udev_device_get_device_type(), g_udev_device_get_device_number(),
 * g_udev_device_get_device_file(),
 * g_udev_device_get_device_file_symlinks().
 *
 * To navigate the device tree, use g_udev_device_get_parent() and
 * g_udev_device_get_parent_with_subsystem().
 *
 * To access udev properties for the device, use
 * g_udev_device_get_property_keys(),
 * g_udev_device_has_property(),
 * g_udev_device_get_property(),
 * g_udev_device_get_property_as_int(),
 * g_udev_device_get_property_as_uint64(),
 * g_udev_device_get_property_as_double(),
 * g_udev_device_get_property_as_boolean() and
 * g_udev_device_get_property_as_strv().
 *
 * To access sysfs attributes for the device, use
 * g_udev_device_get_sysfs_attr(),
 * g_udev_device_get_sysfs_attr_as_int(),
 * g_udev_device_get_sysfs_attr_as_uint64(),
 * g_udev_device_get_sysfs_attr_as_double(),
 * g_udev_device_get_sysfs_attr_as_boolean() and
 * g_udev_device_get_sysfs_attr_as_strv().
 *
 * Note that all getters on #GUdevDevice are non-reffing – returned
 * values are owned by the object, should not be freed and are only
 * valid as long as the object is alive.
 *
 * By design, #GUdevDevice will not react to changes for a device – it
 * only contains a snapshot of information when the #GUdevDevice
 * object was created. To work with changes, you typically connect to
 * the #GUdevClient::uevent signal on a #GUdevClient and get a new
 * #GUdevDevice whenever an event happens.
 */

struct _GUdevDevicePrivate
{
  struct udev_device *udevice;

  /* computed ondemand and cached */
  gchar **device_file_symlinks;
  gchar **property_keys;
  gchar **tags;
  GHashTable *prop_strvs;
  GHashTable *sysfs_attr_strvs;
};

G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)

static void
g_udev_device_finalize (GObject *object)
{
  GUdevDevice *device = G_UDEV_DEVICE (object);

  g_strfreev (device->priv->device_file_symlinks);
  g_strfreev (device->priv->property_keys);
  g_strfreev (device->priv->tags);

  if (device->priv->udevice != NULL)
    udev_device_unref (device->priv->udevice);

  if (device->priv->prop_strvs != NULL)
    g_hash_table_unref (device->priv->prop_strvs);

  if (device->priv->sysfs_attr_strvs != NULL)
    g_hash_table_unref (device->priv->sysfs_attr_strvs);

  if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
    (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
}

static void
g_udev_device_class_init (GUdevDeviceClass *klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  gobject_class->finalize = g_udev_device_finalize;

  g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
}

static void
g_udev_device_init (GUdevDevice *device)
{
  device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
                                              G_UDEV_TYPE_DEVICE,
                                              GUdevDevicePrivate);
}


GUdevDevice *
_g_udev_device_new (struct udev_device *udevice)
{
  GUdevDevice *device;

  device =  G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
  device->priv->udevice = udev_device_ref (udevice);

  return device;
}

/**
 * g_udev_device_get_subsystem:
 * @device: A #GUdevDevice.
 *
 * Gets the subsystem for @device.
 *
 * Returns: The subsystem for @device.
 */
const gchar *
g_udev_device_get_subsystem (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_subsystem (device->priv->udevice);
}

/**
 * g_udev_device_get_devtype:
 * @device: A #GUdevDevice.
 *
 * Gets the device type for @device.
 *
 * Returns: The devtype for @device.
 */
const gchar *
g_udev_device_get_devtype (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_devtype (device->priv->udevice);
}

/**
 * g_udev_device_get_name:
 * @device: A #GUdevDevice.
 *
 * Gets the name of @device, e.g. "sda3".
 *
 * Returns: The name of @device.
 */
const gchar *
g_udev_device_get_name (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_sysname (device->priv->udevice);
}

/**
 * g_udev_device_get_number:
 * @device: A #GUdevDevice.
 *
 * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
 *
 * Returns: The number of @device.
 */
const gchar *
g_udev_device_get_number (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_sysnum (device->priv->udevice);
}

/**
 * g_udev_device_get_sysfs_path:
 * @device: A #GUdevDevice.
 *
 * Gets the sysfs path for @device.
 *
 * Returns: The sysfs path for @device.
 */
const gchar *
g_udev_device_get_sysfs_path (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_syspath (device->priv->udevice);
}

/**
 * g_udev_device_get_driver:
 * @device: A #GUdevDevice.
 *
 * Gets the name of the driver used for @device.
 *
 * Returns: The name of the driver for @device or %NULL if unknown.
 */
const gchar *
g_udev_device_get_driver (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_driver (device->priv->udevice);
}

/**
 * g_udev_device_get_action:
 * @device: A #GUdevDevice.
 *
 * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
 *
 * Returns: An action string.
 */
const gchar *
g_udev_device_get_action (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_action (device->priv->udevice);
}

/**
 * g_udev_device_get_seqnum:
 * @device: A #GUdevDevice.
 *
 * Gets the most recent sequence number for @device.
 *
 * Returns: A sequence number.
 */
guint64
g_udev_device_get_seqnum (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  return udev_device_get_seqnum (device->priv->udevice);
}

/**
 * g_udev_device_get_device_type:
 * @device: A #GUdevDevice.
 *
 * Gets the type of the device file, if any, for @device.
 *
 * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
 */
GUdevDeviceType
g_udev_device_get_device_type (GUdevDevice *device)
{
  struct stat stat_buf;
  const gchar *device_file;
  GUdevDeviceType type;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);

  type = G_UDEV_DEVICE_TYPE_NONE;

  /* TODO: would be better to have support for this in libudev... */

  device_file = g_udev_device_get_device_file (device);
  if (device_file == NULL)
    goto out;

  if (stat (device_file, &stat_buf) != 0)
    goto out;

  if (S_ISBLK (stat_buf.st_mode))
    type = G_UDEV_DEVICE_TYPE_BLOCK;
  else if (S_ISCHR (stat_buf.st_mode))
    type = G_UDEV_DEVICE_TYPE_CHAR;

 out:
  return type;
}

/**
 * g_udev_device_get_device_number:
 * @device: A #GUdevDevice.
 *
 * Gets the device number, if any, for @device.
 *
 * Returns: The device number for @device or 0 if unknown.
 */
GUdevDeviceNumber
g_udev_device_get_device_number (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  return udev_device_get_devnum (device->priv->udevice);
}

/**
 * g_udev_device_get_device_file:
 * @device: A #GUdevDevice.
 *
 * Gets the device file for @device.
 *
 * Returns: The device file for @device or %NULL if no device file
 * exists.
 */
const gchar *
g_udev_device_get_device_file (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  return udev_device_get_devnode (device->priv->udevice);
}

/**
 * g_udev_device_get_device_file_symlinks:
 * @device: A #GUdevDevice.
 *
 * Gets a list of symlinks (in <literal>/dev</literal>) that points to
 * the device file for @device.
 *
 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller.
 */
const gchar * const *
g_udev_device_get_device_file_symlinks (GUdevDevice *device)
{
  struct udev_list_entry *l;
  GPtrArray *p;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);

  if (device->priv->device_file_symlinks != NULL)
    goto out;

  p = g_ptr_array_new ();
  for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
    {
      g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
    }
  g_ptr_array_add (p, NULL);
  device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);

 out:
  return (const gchar * const *) device->priv->device_file_symlinks;
}

/* ---------------------------------------------------------------------------------------------------- */

/**
 * g_udev_device_get_parent:
 * @device: A #GUdevDevice.
 *
 * Gets the immediate parent of @device, if any.
 *
 * Returns: A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref().
 */
GUdevDevice *
g_udev_device_get_parent (GUdevDevice  *device)
{
  GUdevDevice *ret;
  struct udev_device *udevice;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);

  ret = NULL;

  udevice = udev_device_get_parent (device->priv->udevice);
  if (udevice == NULL)
    goto out;

  ret = _g_udev_device_new (udevice);

 out:
  return ret;
}

/**
 * g_udev_device_get_parent_with_subsystem:
 * @device: A #GUdevDevice.
 * @subsystem: The subsystem of the parent to get.
 * @devtype: (allow-none): The devtype of the parent to get or %NULL.
 *
 * Walks up the chain of parents of @device and returns the first
 * device encountered where @subsystem and @devtype matches, if any.
 *
 * Returns: A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref().
 */
GUdevDevice *
g_udev_device_get_parent_with_subsystem (GUdevDevice  *device,
                                         const gchar  *subsystem,
                                         const gchar  *devtype)
{
  GUdevDevice *ret;
  struct udev_device *udevice;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  g_return_val_if_fail (subsystem != NULL, NULL);

  ret = NULL;

  udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
                                                           subsystem,
                                                           devtype);
  if (udevice == NULL)
    goto out;

  ret = _g_udev_device_new (udevice);

 out:
  return ret;
}

/* ---------------------------------------------------------------------------------------------------- */

/**
 * g_udev_device_get_property_keys:
 * @device: A #GUdevDevice.
 *
 * Gets all keys for properties on @device.
 *
 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller.
 */
const gchar* const *
g_udev_device_get_property_keys (GUdevDevice *device)
{
  struct udev_list_entry *l;
  GPtrArray *p;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);

  if (device->priv->property_keys != NULL)
    goto out;

  p = g_ptr_array_new ();
  for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
    {
      g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
    }
  g_ptr_array_add (p, NULL);
  device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);

 out:
  return (const gchar * const *) device->priv->property_keys;
}


/**
 * g_udev_device_has_property:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Check if a the property with the given key exists.
 *
 * Returns: %TRUE only if the value for @key exist.
 */
gboolean
g_udev_device_has_property (GUdevDevice  *device,
                            const gchar  *key)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
  g_return_val_if_fail (key != NULL, FALSE);
  return udev_device_get_property_value (device->priv->udevice, key) != NULL;
}

/**
 * g_udev_device_get_property:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Look up the value for @key on @device.
 *
 * Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device.
 */
const gchar *
g_udev_device_get_property (GUdevDevice  *device,
                            const gchar  *key)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  g_return_val_if_fail (key != NULL, NULL);
  return udev_device_get_property_value (device->priv->udevice, key);
}

/**
 * g_udev_device_get_property_as_int:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Look up the value for @key on @device and convert it to an integer
 * using strtol().
 *
 * Returns: The value for @key or 0 if @key doesn't exist or
 * isn't an integer.
 */
gint
g_udev_device_get_property_as_int (GUdevDevice  *device,
                                   const gchar  *key)
{
  gint result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  g_return_val_if_fail (key != NULL, 0);

  result = 0;
  s = g_udev_device_get_property (device, key);
  if (s == NULL)
    goto out;

  result = strtol (s, NULL, 0);
out:
  return result;
}

/**
 * g_udev_device_get_property_as_uint64:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Look up the value for @key on @device and convert it to an unsigned
 * 64-bit integer using strtoll().
 *
 * Returns: The value  for @key or 0 if @key doesn't  exist or isn't a
 * #guint64.
 */
guint64
g_udev_device_get_property_as_uint64 (GUdevDevice  *device,
                                      const gchar  *key)
{
  guint64 result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  g_return_val_if_fail (key != NULL, 0);

  result = 0;
  s = g_udev_device_get_property (device, key);
  if (s == NULL)
    goto out;

  result = strtoll (s, NULL, 0);
out:
  return result;
}

/**
 * g_udev_device_get_property_as_double:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Look up the value for @key on @device and convert it to a double
 * precision floating point number using strtod().
 *
 * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
 * #gdouble.
 */
gdouble
g_udev_device_get_property_as_double (GUdevDevice  *device,
                                      const gchar  *key)
{
  gdouble result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
  g_return_val_if_fail (key != NULL, 0.0);

  result = 0.0;
  s = g_udev_device_get_property (device, key);
  if (s == NULL)
    goto out;

  result = strtod (s, NULL);
out:
  return result;
}

/**
 * g_udev_device_get_property_as_boolean:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Look up the value for @key on @device and convert it to an
 * boolean. This is done by doing a case-insensitive string comparison
 * on the string value against "1" and "true".
 *
 * Returns: The value for @key or %FALSE if @key doesn't exist or
 * isn't a #gboolean.
 */
gboolean
g_udev_device_get_property_as_boolean (GUdevDevice  *device,
                                       const gchar  *key)
{
  gboolean result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  result = FALSE;
  s = g_udev_device_get_property (device, key);
  if (s == NULL)
    goto out;

  if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
    result = TRUE;
 out:
  return result;
}

static gchar **
split_at_whitespace (const gchar *s)
{
  gchar **result;
  guint n;
  guint m;

  result = g_strsplit_set (s, " \v\t\r\n", 0);

  /* remove empty strings, thanks GLib */
  for (n = 0; result[n] != NULL; n++)
    {
      if (strlen (result[n]) == 0)
        {
          g_free (result[n]);
          for (m = n; result[m] != NULL; m++)
            result[m] = result[m + 1];
          n--;
        }
    }

  return result;
}

/**
 * g_udev_device_get_property_as_strv:
 * @device: A #GUdevDevice.
 * @key: Name of property.
 *
 * Look up the value for @key on @device and return the result of
 * splitting it into non-empty tokens split at white space (only space
 * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
 * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
 * locale is not taken into account).
 *
 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller.
 */
const gchar* const *
g_udev_device_get_property_as_strv (GUdevDevice  *device,
                                    const gchar  *key)
{
  gchar **result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  g_return_val_if_fail (key != NULL, NULL);

  if (device->priv->prop_strvs != NULL)
    {
      result = g_hash_table_lookup (device->priv->prop_strvs, key);
      if (result != NULL)
        goto out;
    }

  result = NULL;
  s = g_udev_device_get_property (device, key);
  if (s == NULL)
    goto out;

  result = split_at_whitespace (s);
  if (result == NULL)
    goto out;

  if (device->priv->prop_strvs == NULL)
    device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
  g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);

out:
  return (const gchar* const *) result;
}

/* ---------------------------------------------------------------------------------------------------- */

/**
 * g_udev_device_get_sysfs_attr:
 * @device: A #GUdevDevice.
 * @name: Name of the sysfs attribute.
 *
 * Look up the sysfs attribute with @name on @device.
 *
 * Returns: The value of the sysfs attribute or %NULL if there is no
 * such attribute. Do not free this string, it is owned by @device.
 */
const gchar *
g_udev_device_get_sysfs_attr (GUdevDevice  *device,
                              const gchar  *name)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  g_return_val_if_fail (name != NULL, NULL);
  return udev_device_get_sysattr_value (device->priv->udevice, name);
}

/**
 * g_udev_device_get_sysfs_attr_as_int:
 * @device: A #GUdevDevice.
 * @name: Name of the sysfs attribute.
 *
 * Look up the sysfs attribute with @name on @device and convert it to an integer
 * using strtol().
 *
 * Returns: The value of the sysfs attribute or 0 if there is no such
 * attribute.
 */
gint
g_udev_device_get_sysfs_attr_as_int (GUdevDevice  *device,
                                     const gchar  *name)
{
  gint result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  g_return_val_if_fail (name != NULL, 0);

  result = 0;
  s = g_udev_device_get_sysfs_attr (device, name);
  if (s == NULL)
    goto out;

  result = strtol (s, NULL, 0);
out:
  return result;
}

/**
 * g_udev_device_get_sysfs_attr_as_uint64:
 * @device: A #GUdevDevice.
 * @name: Name of the sysfs attribute.
 *
 * Look up the sysfs attribute with @name on @device and convert it to an unsigned
 * 64-bit integer using strtoll().
 *
 * Returns: The value of the sysfs attribute or 0 if there is no such
 * attribute.
 */
guint64
g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice  *device,
                                        const gchar  *name)
{
  guint64 result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  g_return_val_if_fail (name != NULL, 0);

  result = 0;
  s = g_udev_device_get_sysfs_attr (device, name);
  if (s == NULL)
    goto out;

  result = strtoll (s, NULL, 0);
out:
  return result;
}

/**
 * g_udev_device_get_sysfs_attr_as_double:
 * @device: A #GUdevDevice.
 * @name: Name of the sysfs attribute.
 *
 * Look up the sysfs attribute with @name on @device and convert it to a double
 * precision floating point number using strtod().
 *
 * Returns: The value of the sysfs attribute or 0.0 if there is no such
 * attribute.
 */
gdouble
g_udev_device_get_sysfs_attr_as_double (GUdevDevice  *device,
                                        const gchar  *name)
{
  gdouble result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
  g_return_val_if_fail (name != NULL, 0.0);

  result = 0.0;
  s = g_udev_device_get_sysfs_attr (device, name);
  if (s == NULL)
    goto out;

  result = strtod (s, NULL);
out:
  return result;
}

/**
 * g_udev_device_get_sysfs_attr_as_boolean:
 * @device: A #GUdevDevice.
 * @name: Name of the sysfs attribute.
 *
 * Look up the sysfs attribute with @name on @device and convert it to an
 * boolean. This is done by doing a case-insensitive string comparison
 * on the string value against "1" and "true".
 *
 * Returns: The value of the sysfs attribute or %FALSE if there is no such
 * attribute.
 */
gboolean
g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice  *device,
                                         const gchar  *name)
{
  gboolean result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
  g_return_val_if_fail (name != NULL, FALSE);

  result = FALSE;
  s = g_udev_device_get_sysfs_attr (device, name);
  if (s == NULL)
    goto out;

  if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
    result = TRUE;
 out:
  return result;
}

/**
 * g_udev_device_get_sysfs_attr_as_strv:
 * @device: A #GUdevDevice.
 * @name: Name of the sysfs attribute.
 *
 * Look up the sysfs attribute with @name on @device and return the result of
 * splitting it into non-empty tokens split at white space (only space (' '),
 * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
 * tab ('\t'), and vertical tab ('\v') are considered; the locale is
 * not taken into account).
 *
 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller.
 */
const gchar * const *
g_udev_device_get_sysfs_attr_as_strv (GUdevDevice  *device,
                                      const gchar  *name)
{
  gchar **result;
  const gchar *s;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  if (device->priv->sysfs_attr_strvs != NULL)
    {
      result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
      if (result != NULL)
        goto out;
    }

  result = NULL;
  s = g_udev_device_get_sysfs_attr (device, name);
  if (s == NULL)
    goto out;

  result = split_at_whitespace (s);
  if (result == NULL)
    goto out;

  if (device->priv->sysfs_attr_strvs == NULL)
    device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
  g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);

out:
  return (const gchar* const *) result;
}

/**
 * g_udev_device_get_tags:
 * @device: A #GUdevDevice.
 *
 * Gets all tags for @device.
 *
 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller.
 *
 * Since: 165
 */
const gchar* const *
g_udev_device_get_tags (GUdevDevice  *device)
{
  struct udev_list_entry *l;
  GPtrArray *p;

  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);

  if (device->priv->tags != NULL)
    goto out;

  p = g_ptr_array_new ();
  for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
    {
      g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
    }
  g_ptr_array_add (p, NULL);
  device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);

 out:
  return (const gchar * const *) device->priv->tags;
}

/**
 * g_udev_device_get_is_initialized:
 * @device: A #GUdevDevice.
 *
 * Gets whether @device has been initalized.
 *
 * Returns: Whether @device has been initialized.
 *
 * Since: 165
 */
gboolean
g_udev_device_get_is_initialized (GUdevDevice  *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
  return udev_device_get_is_initialized (device->priv->udevice);
}

/**
 * g_udev_device_get_usec_since_initialized:
 * @device: A #GUdevDevice.
 *
 * Gets number of micro-seconds since @device was initialized.
 *
 * This only works for devices with properties in the udev
 * database. All other devices return 0.
 *
 * Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
 *
 * Since: 165
 */
guint64
g_udev_device_get_usec_since_initialized (GUdevDevice *device)
{
  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
  return udev_device_get_usec_since_initialized (device->priv->udevice);
}

