<commit_before>/*
 * wocky-xmpp-node.c - Code for Wocky xmpp nodes
 * Copyright (C) 2006 Collabora Ltd.
 * @author <NAME> <<EMAIL>>
 *
 * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <glib.h>
#include <string.h>

#include "wocky-xmpp-node.h"
#include "wocky-utils.h"
#include "wocky-namespaces.h"

typedef struct {
  gchar *key;
  gchar *value;
  gchar *prefix;
  GQuark ns;
} Attribute;

typedef struct {
  const gchar *key;
  GQuark ns;
} Tuple;

typedef struct {
  const gchar *ns_urn;
  gchar *prefix;
  GQuark ns;
} NSPrefix;

static NSPrefix default_attr_ns_prefixes[] =
  { { WOCKY_GOOGLE_NS_AUTH, "ga" },
    { NULL, NULL } };

static GSList *attr_ns_prefixes;

WockyXmppNode *
wocky_xmpp_node_new (const char *name)
{
  WockyXmppNode *result = g_slice_new0 (WockyXmppNode);

  result->name = g_strdup (name);

  return result;
}

static void
attribute_free (Attribute *a)
{
  g_free (a->key);
  g_free (a->value);
  g_free (a->prefix);
  g_slice_free (Attribute, a);
}

/* Frees the node and all it's children */
void
wocky_xmpp_node_free (WockyXmppNode *node)
{
  GSList *l;

  if (node == NULL)
    {
      return ;
    }

  g_free (node->name);
  g_free (node->content);
  g_free (node->language);

  for (l = node->children; l != NULL ; l = l->next)
    {
      wocky_xmpp_node_free ((WockyXmppNode *) l->data);
    }
  g_slist_free (node->children);

  for (l = node->attributes; l != NULL ; l = l->next)
    {
      Attribute *a = (Attribute *) l->data;
      attribute_free (a);
    }
  g_slist_free (node->attributes);

  g_slice_free (WockyXmppNode, node);
}

void
wocky_xmpp_node_each_attribute (WockyXmppNode *node,
    wocky_xmpp_node_each_attr_func func, gpointer user_data)
{
  GSList *l;

  for (l = node->attributes; l != NULL ; l = l->next)
    {
      Attribute *a = (Attribute *) l->data;
      const gchar *ns = g_quark_to_string (a->ns);
      if (!func (a->key, a->value, a->prefix, ns, user_data))
        {
          return;
        }
    }
}

void
wocky_xmpp_node_each_child (WockyXmppNode *node,
    wocky_xmpp_node_each_child_func func, gpointer user_data)
{
  GSList *l;

  for (l = node->children; l != NULL ; l = l->next)
    {
      WockyXmppNode *n = (WockyXmppNode *) l->data;
      if (!func (n, user_data))
        {
          return;
        }
    }
}

static gint
attribute_compare (gconstpointer a, gconstpointer b)
{
  const Attribute *attr = (const Attribute *)a;
  const Tuple *target = (const Tuple *)b;

  if (target->ns != 0 && attr->ns != target->ns)
    {
      return 1;
    }

  return strcmp (attr->key, target->key);
}

const gchar *
wocky_xmpp_node_get_attribute_ns (WockyXmppNode *node,
    const gchar *key, const gchar *ns)
{
  GSList *link;
  Tuple search;

  search.key = (gchar *) key;
  search.ns = (ns != NULL ? g_quark_from_string (ns) : 0);

  link = g_slist_find_custom (node->attributes, &search, attribute_compare);

  return (link == NULL) ? NULL : ((Attribute *) (link->data))->value;
}

const gchar *
wocky_xmpp_node_get_attribute (WockyXmppNode *node, const gchar *key)
{
  return wocky_xmpp_node_get_attribute_ns (node, key, NULL);
}

void
wocky_xmpp_node_set_attribute (WockyXmppNode *node,
    const gchar *key, const gchar *value)
{
  g_assert (value != NULL);
  wocky_xmpp_node_set_attribute_n_ns (node, key, value, strlen (value), NULL);
}

void
wocky_xmpp_node_set_attribute_ns (WockyXmppNode *node, const gchar *key,
    const gchar *value, const gchar *ns)
{
  wocky_xmpp_node_set_attribute_n_ns (node,
      key, value, strlen (value), ns);
}

/* this takes posession of the gchar *prefix passed in */
static NSPrefix *
ns_prefix_new (const gchar *urn,
    GQuark ns,
    gchar *prefix)
{
  NSPrefix *nsp = g_new0 (NSPrefix, 1);
  nsp->ns_urn = urn;
  nsp->prefix = prefix;
  nsp->ns = ns;

  return nsp;
}

static const gchar *
_generate_ns_prefix (const gchar *urn, GQuark ns)
{
  NSPrefix *nsp = NULL;
  GString *prefix = g_string_new ("wocky-");
  int p = ns;

  while (p > 0)
    {
      guchar x = (p % 26);
      p -= x;
      p /= 26;
      x += 'a';
      g_string_append_c (prefix, x);
    }

  nsp = ns_prefix_new (urn, ns, g_string_free (prefix, FALSE));
  attr_ns_prefixes = g_slist_prepend (attr_ns_prefixes, nsp);<commit_msg>g_slice_new0 instead of g_new0 in ns_prefix_new.<commit_after>/*
 * wocky-xmpp-node.c - Code for Wocky xmpp nodes
 * Copyright (C) 2006 Collabora Ltd.
 * @author <NAME> <<EMAIL>>
 *
 * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <glib.h>
#include <string.h>

#include "wocky-xmpp-node.h"
#include "wocky-utils.h"
#include "wocky-namespaces.h"

typedef struct {
  gchar *key;
  gchar *value;
  gchar *prefix;
  GQuark ns;
} Attribute;

typedef struct {
  const gchar *key;
  GQuark ns;
} Tuple;

typedef struct {
  const gchar *ns_urn;
  gchar *prefix;
  GQuark ns;
} NSPrefix;

static NSPrefix default_attr_ns_prefixes[] =
  { { WOCKY_GOOGLE_NS_AUTH, "ga" },
    { NULL, NULL } };

static GSList *attr_ns_prefixes;

WockyXmppNode *
wocky_xmpp_node_new (const char *name)
{
  WockyXmppNode *result = g_slice_new0 (WockyXmppNode);

  result->name = g_strdup (name);

  return result;
}

static void
attribute_free (Attribute *a)
{
  g_free (a->key);
  g_free (a->value);
  g_free (a->prefix);
  g_slice_free (Attribute, a);
}

/* Frees the node and all it's children */
void
wocky_xmpp_node_free (WockyXmppNode *node)
{
  GSList *l;

  if (node == NULL)
    {
      return ;
    }

  g_free (node->name);
  g_free (node->content);
  g_free (node->language);

  for (l = node->children; l != NULL ; l = l->next)
    {
      wocky_xmpp_node_free ((WockyXmppNode *) l->data);
    }
  g_slist_free (node->children);

  for (l = node->attributes; l != NULL ; l = l->next)
    {
      Attribute *a = (Attribute *) l->data;
      attribute_free (a);
    }
  g_slist_free (node->attributes);

  g_slice_free (WockyXmppNode, node);
}

void
wocky_xmpp_node_each_attribute (WockyXmppNode *node,
    wocky_xmpp_node_each_attr_func func, gpointer user_data)
{
  GSList *l;

  for (l = node->attributes; l != NULL ; l = l->next)
    {
      Attribute *a = (Attribute *) l->data;
      const gchar *ns = g_quark_to_string (a->ns);
      if (!func (a->key, a->value, a->prefix, ns, user_data))
        {
          return;
        }
    }
}

void
wocky_xmpp_node_each_child (WockyXmppNode *node,
    wocky_xmpp_node_each_child_func func, gpointer user_data)
{
  GSList *l;

  for (l = node->children; l != NULL ; l = l->next)
    {
      WockyXmppNode *n = (WockyXmppNode *) l->data;
      if (!func (n, user_data))
        {
          return;
        }
    }
}

static gint
attribute_compare (gconstpointer a, gconstpointer b)
{
  const Attribute *attr = (const Attribute *)a;
  const Tuple *target = (const Tuple *)b;

  if (target->ns != 0 && attr->ns != target->ns)
    {
      return 1;
    }

  return strcmp (attr->key, target->key);
}

const gchar *
wocky_xmpp_node_get_attribute_ns (WockyXmppNode *node,
    const gchar *key, const gchar *ns)
{
  GSList *link;
  Tuple search;

  search.key = (gchar *) key;
  search.ns = (ns != NULL ? g_quark_from_string (ns) : 0);

  link = g_slist_find_custom (node->attributes, &search, attribute_compare);

  return (link == NULL) ? NULL : ((Attribute *) (link->data))->value;
}

const gchar *
wocky_xmpp_node_get_attribute (WockyXmppNode *node, const gchar *key)
{
  return wocky_xmpp_node_get_attribute_ns (node, key, NULL);
}

void
wocky_xmpp_node_set_attribute (WockyXmppNode *node,
    const gchar *key, const gchar *value)
{
  g_assert (value != NULL);
  wocky_xmpp_node_set_attribute_n_ns (node, key, value, strlen (value), NULL);
}

void
wocky_xmpp_node_set_attribute_ns (WockyXmppNode *node, const gchar *key,
    const gchar *value, const gchar *ns)
{
  wocky_xmpp_node_set_attribute_n_ns (node,
      key, value, strlen (value), ns);
}

/* this takes posession of the gchar *prefix passed in */
static NSPrefix *
ns_prefix_new (const gchar *urn,
    GQuark ns,
    gchar *prefix)
{
  NSPrefix *nsp = g_slice_new0 (NSPrefix);
  nsp->ns_urn = urn;
  nsp->prefix = prefix;
  nsp->ns = ns;

  return nsp;
}

static const gchar *
_generate_ns_prefix (const gchar *urn, GQuark ns)
{
  NSPrefix *nsp = NULL;
  GString *prefix = g_string_new ("wocky-");
  int p = ns;

  while (p > 0)
    {
      guchar x = (p % 26);
      p -= x;
      p /= 26;
      x += 'a';
      g_string_append_c (prefix, x);
    }

  nsp = ns_prefix_new (urn, ns, g_string_free (prefix, FALSE));
  attr_ns_prefixes = g_slist_prepend (attr_ns_prefixes, nsp);
{'fraction_non_alphanumeric': 0.12184279652455042, 'fraction_numerical': 0.005758739139220044, 'mean_word_length': 3.3646384479717812, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7624731', 'n_tokens_mistral': 3883, 'n_tokens_neox': 3781, 'n_words': 1037}