Blame src/libotutil/ot-variant-utils.c

rpm-build 0fba15
/*
rpm-build 0fba15
 * Copyright (C) 2011 Colin Walters <walters@verbum.org>
rpm-build 0fba15
 *
rpm-build 0fba15
 * SPDX-License-Identifier: LGPL-2.0+
rpm-build 0fba15
 *
rpm-build 0fba15
 * This library is free software; you can redistribute it and/or
rpm-build 0fba15
 * modify it under the terms of the GNU Lesser General Public
rpm-build 0fba15
 * License as published by the Free Software Foundation; either
rpm-build 0fba15
 * version 2 of the License, or (at your option) any later version.
rpm-build 0fba15
 *
rpm-build 0fba15
 * This library is distributed in the hope that it will be useful,
rpm-build 0fba15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rpm-build 0fba15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
rpm-build 0fba15
 * Lesser General Public License for more details.
rpm-build 0fba15
 *
rpm-build 0fba15
 * You should have received a copy of the GNU Lesser General Public
rpm-build 0fba15
 * License along with this library; if not, write to the
rpm-build 0fba15
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
rpm-build 0fba15
 * Boston, MA 02111-1307, USA.
rpm-build 0fba15
 *
rpm-build 0fba15
 * Author: Colin Walters <walters@verbum.org>
rpm-build 0fba15
 */
rpm-build 0fba15
rpm-build 0fba15
#include "config.h"
rpm-build 0fba15
rpm-build 0fba15
#include <gio/gio.h>
rpm-build 0fba15
#include <gio/gfiledescriptorbased.h>
rpm-build 0fba15
rpm-build 0fba15
#include <string.h>
rpm-build 0fba15
rpm-build 0fba15
#include "otutil.h"
rpm-build 0fba15
rpm-build 0fba15
/* Create a new GVariant empty GVariant of type a{sv} */
rpm-build 0fba15
GVariant *
rpm-build 0fba15
ot_gvariant_new_empty_string_dict (void)
rpm-build 0fba15
{
rpm-build 0fba15
  g_auto(GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER;
rpm-build 0fba15
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
rpm-build 0fba15
  return g_variant_builder_end (&builder);
rpm-build 0fba15
}
rpm-build 0fba15
rpm-build 0fba15
rpm-build 0fba15
/* Create a new GVariant of type ay from the raw @data pointer */
rpm-build 0fba15
GVariant *
rpm-build 0fba15
ot_gvariant_new_bytearray (const guchar   *data,
rpm-build 0fba15
                           gsize           len)
rpm-build 0fba15
{
rpm-build 0fba15
  gpointer data_copy = g_memdup (data, len);
rpm-build 0fba15
  GVariant *ret = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data_copy,
rpm-build 0fba15
                                 len, FALSE, g_free, data_copy);
rpm-build 0fba15
  return ret;
rpm-build 0fba15
}
rpm-build 0fba15
rpm-build 0fba15
/* Convert a GBytes into a GVariant of type ay (byte array) */
rpm-build 0fba15
GVariant *
rpm-build 0fba15
ot_gvariant_new_ay_bytes (GBytes *bytes)
rpm-build 0fba15
{
rpm-build 0fba15
  gsize size;
rpm-build 0fba15
  gconstpointer data = g_bytes_get_data (bytes, &size);
rpm-build 0fba15
  g_bytes_ref (bytes);
rpm-build 0fba15
  return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size,
rpm-build 0fba15
                                  TRUE, (GDestroyNotify)g_bytes_unref, bytes);
rpm-build 0fba15
}
rpm-build 0fba15
rpm-build 0fba15
/* Create a GVariant in @out_variant that is backed by
rpm-build 0fba15
 * the data from @fd, starting at @start.  If the data is
rpm-build 0fba15
 * large enough, mmap() may be used.  @trusted is used
rpm-build 0fba15
 * by the GVariant core; see g_variant_new_from_data().
rpm-build 0fba15
 */
rpm-build 0fba15
gboolean
rpm-build 0fba15
ot_variant_read_fd (int                    fd,
rpm-build 0fba15
                    goffset                start,
rpm-build 0fba15
                    const GVariantType    *type,
rpm-build 0fba15
                    gboolean               trusted,
rpm-build 0fba15
                    GVariant             **out_variant,
rpm-build 0fba15
                    GError               **error)
rpm-build 0fba15
{
rpm-build 0fba15
  g_autoptr(GBytes) bytes = ot_fd_readall_or_mmap (fd, start, error);
rpm-build 0fba15
  if (!bytes)
rpm-build 0fba15
    return FALSE;
rpm-build 0fba15
rpm-build 0fba15
  *out_variant = g_variant_ref_sink (g_variant_new_from_bytes (type, bytes, trusted));
rpm-build 0fba15
  return TRUE;
rpm-build 0fba15
}
rpm-build 0fba15
rpm-build 0fba15
/* GVariants are immutable; this function allows generating an open builder
rpm-build 0fba15
 * for a new variant, inherting the data from @variant.
rpm-build 0fba15
 */
rpm-build 0fba15
GVariantBuilder *
rpm-build 0fba15
ot_util_variant_builder_from_variant (GVariant            *variant,
rpm-build 0fba15
                                      const GVariantType  *type)
rpm-build 0fba15
{
rpm-build 0fba15
  GVariantBuilder *builder = g_variant_builder_new (type);
rpm-build 0fba15
rpm-build 0fba15
  if (variant != NULL)
rpm-build 0fba15
    {
rpm-build 0fba15
      const int n = g_variant_n_children (variant);
rpm-build 0fba15
      for (int i = 0; i < n; i++)
rpm-build 0fba15
        {
rpm-build 0fba15
          g_autoptr(GVariant) child = g_variant_get_child_value (variant, i);
rpm-build 0fba15
          g_variant_builder_add_value (builder, child);
rpm-build 0fba15
        }
rpm-build 0fba15
    }
rpm-build 0fba15
rpm-build 0fba15
  return builder;
rpm-build 0fba15
}
rpm-build 0fba15
rpm-build 0fba15
/**
rpm-build 0fba15
 * ot_variant_bsearch_str:
rpm-build 0fba15
 * @array: A GVariant array whose first element must be a string
rpm-build 0fba15
 * @str: Search for this string
rpm-build 0fba15
 * @out_pos: Output position
rpm-build 0fba15
 *
rpm-build 0fba15
 *
rpm-build 0fba15
 * Binary search in a GVariant array, which must be of the form 'a(s...)',
rpm-build 0fba15
 * where '...' may be anything.  The array elements must be sorted.
rpm-build 0fba15
 *
rpm-build 0fba15
 * Returns: %TRUE if found, %FALSE otherwise
rpm-build 0fba15
 */
rpm-build 0fba15
gboolean
rpm-build 0fba15
ot_variant_bsearch_str (GVariant   *array,
rpm-build 0fba15
                        const char *str,
rpm-build 0fba15
                        int        *out_pos)
rpm-build 0fba15
{
rpm-build 0fba15
  const gsize n = g_variant_n_children (array);
rpm-build 0fba15
  if (n == 0)
rpm-build 0fba15
    return FALSE;
rpm-build 0fba15
rpm-build 0fba15
  gsize imax = n - 1;
rpm-build 0fba15
  gsize imin = 0;
rpm-build 0fba15
  gsize imid = -1;
rpm-build 0fba15
  while (imax >= imin)
rpm-build 0fba15
    {
rpm-build 0fba15
      const char *cur;
rpm-build 0fba15
rpm-build 0fba15
      imid = (imin + imax) / 2;
rpm-build 0fba15
rpm-build 0fba15
      g_autoptr(GVariant) child = g_variant_get_child_value (array, imid);
rpm-build 0fba15
      g_variant_get_child (child, 0, "&s", &cur, NULL);
rpm-build 0fba15
rpm-build 0fba15
      int cmp = strcmp (cur, str);
rpm-build 0fba15
      if (cmp < 0)
rpm-build 0fba15
        imin = imid + 1;
rpm-build 0fba15
      else if (cmp > 0)
rpm-build 0fba15
        {
rpm-build 0fba15
          if (imid == 0)
rpm-build 0fba15
            break;
rpm-build 0fba15
          imax = imid - 1;
rpm-build 0fba15
        }
rpm-build 0fba15
      else
rpm-build 0fba15
        {
rpm-build 0fba15
          *out_pos = imid;
rpm-build 0fba15
          return TRUE;
rpm-build 0fba15
        }
rpm-build 0fba15
    }
rpm-build 0fba15
rpm-build 0fba15
  *out_pos = imid;
rpm-build 0fba15
  return FALSE;
rpm-build 0fba15
}