コード例 #1
0
static GArray*
inf_adopted_session_get_xml_user_props(InfSession* session,
                                       InfXmlConnection* conn,
                                       const xmlNodePtr xml)
{
  GArray* array;
  GParameter* parameter;
  InfAdoptedStateVector* vector;
  xmlChar* time;

  array = INF_SESSION_CLASS(parent_class)->get_xml_user_props(
    session,
    conn,
    xml
  );

  /* Vector time */
  time = inf_xml_util_get_attribute(xml, "time");
  if(time != NULL)
  {
    vector = inf_adopted_state_vector_from_string((const gchar*)time, NULL);
    xmlFree(time);

    /* TODO: Error reporting for get_xml_user_props */
    if(vector != NULL)
    {
      parameter = inf_session_get_user_property(array, "vector");
      g_value_init(&parameter->value, INF_ADOPTED_TYPE_STATE_VECTOR);
      g_value_take_boxed(&parameter->value, vector);
    }
  }

  /* log-begin is not in the  spec */
#if 0
  /* Initial request log, only if ID is also given */
  id_param = inf_session_lookup_user_property(
    (const GParameter*)array->data,
    array->len,
    "id"
  );

  if(id_param != NULL &&
     inf_xml_util_get_attribute_uint(xml, "log-begin", &log_begin, NULL))
  {
    log = inf_adopted_request_log_new(
      g_value_get_uint(&id_param->value),
      log_begin
    );

    parameter = inf_session_get_user_property(array, "request-log");
    g_value_init(&parameter->value, INF_ADOPTED_TYPE_REQUEST_LOG);
    g_value_take_object(&parameter->value, log);
  }
#endif

  return array;
}
コード例 #2
0
static void
inf_adopted_session_set_xml_user_props(InfSession* session,
                                       const GParameter* params,
                                       guint n_params,
                                       xmlNodePtr xml)
{
  const GParameter* time;
  InfAdoptedStateVector* vector;
  gchar* time_string;

  INF_SESSION_CLASS(parent_class)->set_xml_user_props(
    session,
    params,
    n_params,
    xml
  );

  time = inf_session_lookup_user_property(params, n_params, "vector");
  if(time != NULL)
  {
    vector = (InfAdoptedStateVector*)g_value_get_boxed(&time->value);
    time_string = inf_adopted_state_vector_to_string(vector);
    inf_xml_util_set_attribute(xml, "time", time_string);
    g_free(time_string);
  }

  /* log-begin is not in the spec */
#if 0
  log = inf_session_lookup_user_property(params, n_params, "request-log");
  if(log != NULL)
  {
    log_begin = inf_adopted_request_log_get_begin(
      INF_ADOPTED_REQUEST_LOG(g_value_get_object(&log->value))
    );

    inf_xml_util_set_attribute_uint(xml, "log-begin", log_begin);
  }
#endif
}
コード例 #3
0
static gboolean
inf_adopted_session_validate_user_props(InfSession* session,
                                        const GParameter* params,
                                        guint n_params,
                                        InfUser* exclude,
                                        GError** error)
{
  const GParameter* time;
  gboolean result;

  result = INF_SESSION_CLASS(parent_class)->validate_user_props(
    session,
    params,
    n_params,
    exclude,
    error
  );

  if(result == FALSE) return FALSE;

  time = inf_session_lookup_user_property(params, n_params, "vector");
  if(time == NULL)
  {
    g_set_error(
      error,
      inf_adopted_session_error_quark,
      INF_ADOPTED_SESSION_ERROR_MISSING_STATE_VECTOR,
      "%s",
      _("'time' attribute in user message is missing")
    );

    return FALSE;
  }

  return TRUE;
}
コード例 #4
0
ファイル: infc-session-proxy.c プロジェクト: pkern/infinote
static gboolean
infc_session_proxy_handle_user_rejoin(InfcSessionProxy* proxy,
                                      InfXmlConnection* connection,
                                      xmlNodePtr xml,
                                      GError** error)
{
  InfcSessionProxyPrivate* priv;
  InfSessionClass* session_class;
  GArray* array;
  InfUser* user;
  const GParameter* idparam;
  GParameter* param;
  guint id;
  gboolean result;
  guint i;

  priv = INFC_SESSION_PROXY_PRIVATE(proxy);
  session_class = INF_SESSION_GET_CLASS(priv->session);

  array = session_class->get_xml_user_props(priv->session, connection, xml);

  /* Find rejoining user first */
  idparam = inf_session_lookup_user_property(
    (const GParameter*)array->data,
    array->len,
    "id"
  );

  if(idparam == NULL)
  {
    g_set_error(
      error,
      inf_request_error_quark(),
      INF_REQUEST_ERROR_NO_SUCH_ATTRIBUTE,
      _("Request does not contain required attribute 'id'")
    );

    goto error;
  }

  id = g_value_get_uint(&idparam->value);
  user = inf_user_table_lookup_user_by_id(
    inf_session_get_user_table(priv->session),
    id
  );

  if(user == NULL)
  {
    g_set_error(
      error,
      inf_user_error_quark(),
      INF_USER_ERROR_NO_SUCH_USER,
      _("No such user with ID %u"),
      id
    );

    goto error;
  }

  /* Set local flag if the join was requested by us (seq is present in
   * server response). */
  param = inf_session_get_user_property(array, "flags");
  g_assert(!G_IS_VALUE(&param->value)); /* must not have been set already */

  g_value_init(&param->value, INF_TYPE_USER_FLAGS);
  if(xmlHasProp(xml, (const xmlChar*)"seq") != NULL)
    g_value_set_flags(&param->value, INF_USER_LOCAL);
  else
    g_value_set_flags(&param->value, 0);

  /* Set connection. If none was given, use publisher connection */
  param = inf_session_get_user_property(array, "connection");
  if(!G_IS_VALUE(&param->value))
  {
    g_value_init(&param->value, INF_TYPE_XML_CONNECTION);
    g_value_set_object(&param->value, G_OBJECT(connection));
  }

  result = session_class->validate_user_props(
    priv->session,
    (const GParameter*)array->data,
    array->len,
    user,
    error
  );

  if(result == FALSE)
    goto error;

  /* Set properties on the found user object, performing the rejoin */
  g_object_freeze_notify(G_OBJECT(user));

  for(i = 0; i < array->len; ++ i)
  {
    param = &g_array_index(array, GParameter, i);

    /* Don't set ID because the ID is the same anyway (we did the user lookup
     * by it). The "id" property is construct only anyway. */
    if(strcmp(param->name, "id") != 0)
      g_object_set_property(G_OBJECT(user), param->name, &param->value);
  }

  /* TODO: Set user status to available, if the server did not send the
   * status property? Require the status property being set on a rejoin?
   * Make sure it is not unavailable? */

  g_object_thaw_notify(G_OBJECT(user));
  for(i = 0; i < array->len; ++ i)
    g_value_unset(&g_array_index(array, GParameter, i).value);
  g_array_free(array, TRUE);

  infc_session_proxy_succeed_user_request(proxy, xml, user);

  return TRUE;

error:
  for(i = 0; i < array->len; ++ i)
    g_value_unset(&g_array_index(array, GParameter, i).value);
  g_array_free(array, TRUE);
  return FALSE;
}