<commit_before>
#define _GNU_SOURCE
#include "config.h"
#include "conn-location.h"

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

#define DEBUG_FLAG GABBLE_DEBUG_LOCATION

#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>

#include "debug.h"
#include "namespaces.h"
#include "presence-cache.h"
#include "util.h"

typedef struct
{
  gchar *xmpp_name;
  gchar *tp_name;
  GType type;
} LocationMapping;

static const LocationMapping mappings[] = {
  { "alt", "alt", G_TYPE_DOUBLE },
  { "area", "area", G_TYPE_STRING },
  { "bearing", "bearing", G_TYPE_DOUBLE },
  { "building", "building", G_TYPE_STRING },
  { "country", "country", G_TYPE_STRING },
  { "description", "description", G_TYPE_STRING },
  { "floor", "floor", G_TYPE_STRING },
  { "lat", "lat", G_TYPE_DOUBLE },
  { "locality", "locality", G_TYPE_STRING },
  { "lon", "lon", G_TYPE_DOUBLE },
  { "postalcode", "postalcode", G_TYPE_STRING },
  { "region", "region", G_TYPE_STRING },
  { "room", "room", G_TYPE_STRING },
  { "speed", "speed", G_TYPE_DOUBLE },
  { "street", "street", G_TYPE_STRING },
  { "text", "text", G_TYPE_STRING },
  { "timestamp", "timestamp", G_TYPE_INT64 },
  { "uri", "uri", G_TYPE_STRING },
  { "accuracy", "accuracy", G_TYPE_DOUBLE },
  { "countrycode", "countrycode", G_TYPE_STRING },
  /* language is a special case as it's not mapped on a node but on the
   * xml:lang attribute of the 'geoloc' node. */
  { NULL, NULL },
};

static GHashTable *xmpp_to_tp = NULL;
static GHashTable *tp_to_xmpp = NULL;

static void
build_mapping_tables (void)
{
  guint i;

  if (xmpp_to_tp != NULL)
    return;
  g_assert (tp_to_xmpp == NULL);

  xmpp_to_tp = g_hash_table_new (g_str_hash, g_str_equal);
  tp_to_xmpp = g_hash_table_new (g_str_hash, g_str_equal);

  for (i = 0; mappings[i].xmpp_name != NULL; i++)
    {
      g_hash_table_insert (xmpp_to_tp, mappings[i].xmpp_name,
          (gpointer) &mappings[i]);
      g_hash_table_insert (tp_to_xmpp, mappings[i].tp_name,
          (gpointer) &mappings[i]);
    }
}

static gboolean update_location_from_msg (GabbleConnection *conn,
    const gchar *from, LmMessage *msg);

static GHashTable *
get_cached_location (GabbleConnection *conn,
    TpHandle handle)
{
  TpBaseConnection *base = (TpBaseConnection *) conn;
  GHashTable *location;
  const gchar *jid;
  TpHandleRepoIface *contact_repo;

  contact_repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT);
  jid = tp_handle_inspect (contact_repo, handle);

  location = gabble_presence_cache_get_location (conn->presence_cache, handle);

  if (location != NULL)
    DEBUG (" - %s: cached", jid);
  else
    DEBUG (" - %s: unknown", jid);

  return location;
}

static void
location_get_locations (TpSvcConnectionInterfaceLocation *iface,
                        const GArray *contacts,
                        DBusGMethodInvocation *context)<commit_msg>Location: better document location dictionary refcounting<commit_after>
#define _GNU_SOURCE
#include "config.h"
#include "conn-location.h"

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

#define DEBUG_FLAG GABBLE_DEBUG_LOCATION

#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>

#include "debug.h"
#include "namespaces.h"
#include "presence-cache.h"
#include "util.h"

typedef struct
{
  gchar *xmpp_name;
  gchar *tp_name;
  GType type;
} LocationMapping;

static const LocationMapping mappings[] = {
  { "alt", "alt", G_TYPE_DOUBLE },
  { "area", "area", G_TYPE_STRING },
  { "bearing", "bearing", G_TYPE_DOUBLE },
  { "building", "building", G_TYPE_STRING },
  { "country", "country", G_TYPE_STRING },
  { "description", "description", G_TYPE_STRING },
  { "floor", "floor", G_TYPE_STRING },
  { "lat", "lat", G_TYPE_DOUBLE },
  { "locality", "locality", G_TYPE_STRING },
  { "lon", "lon", G_TYPE_DOUBLE },
  { "postalcode", "postalcode", G_TYPE_STRING },
  { "region", "region", G_TYPE_STRING },
  { "room", "room", G_TYPE_STRING },
  { "speed", "speed", G_TYPE_DOUBLE },
  { "street", "street", G_TYPE_STRING },
  { "text", "text", G_TYPE_STRING },
  { "timestamp", "timestamp", G_TYPE_INT64 },
  { "uri", "uri", G_TYPE_STRING },
  { "accuracy", "accuracy", G_TYPE_DOUBLE },
  { "countrycode", "countrycode", G_TYPE_STRING },
  /* language is a special case as it's not mapped on a node but on the
   * xml:lang attribute of the 'geoloc' node. */
  { NULL, NULL },
};

static GHashTable *xmpp_to_tp = NULL;
static GHashTable *tp_to_xmpp = NULL;

static void
build_mapping_tables (void)
{
  guint i;

  if (xmpp_to_tp != NULL)
    return;
  g_assert (tp_to_xmpp == NULL);

  xmpp_to_tp = g_hash_table_new (g_str_hash, g_str_equal);
  tp_to_xmpp = g_hash_table_new (g_str_hash, g_str_equal);

  for (i = 0; mappings[i].xmpp_name != NULL; i++)
    {
      g_hash_table_insert (xmpp_to_tp, mappings[i].xmpp_name,
          (gpointer) &mappings[i]);
      g_hash_table_insert (tp_to_xmpp, mappings[i].tp_name,
          (gpointer) &mappings[i]);
    }
}

static gboolean update_location_from_msg (GabbleConnection *conn,
    const gchar *from, LmMessage *msg);

/*
 * get_cached_location:
 * @conn: a connection
 * @handle: a handle, which must have been pre-validated.
 *
 * Returns: a new ref to a GHashTable containing @handle's location, or %NULL
 *          if we have no cached location.
 */
static GHashTable *
get_cached_location (GabbleConnection *conn,
    TpHandle handle)
{
  TpBaseConnection *base = (TpBaseConnection *) conn;
  GHashTable *location;
  const gchar *jid;
  TpHandleRepoIface *contact_repo;

  contact_repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT);
  jid = tp_handle_inspect (contact_repo, handle);

  location = gabble_presence_cache_get_location (conn->presence_cache, handle);

  if (location != NULL)
    DEBUG (" - %s: cached", jid);
  else
    DEBUG (" - %s: unknown", jid);

  return location;
}

static void
location_get_locations (TpSvcConnectionInterfaceLocation *iface,
                        const GArray *contacts,
                        DBusGMethodInvocation *context)
{'fraction_non_alphanumeric': 0.13818845388188453, 'fraction_numerical': 0.0009953550099535502, 'mean_word_length': 4.256320836965998, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '7107745', 'n_tokens_mistral': 2253, 'n_tokens_neox': 2204, 'n_words': 496}