static InfAdoptedUser* inf_adopted_session_user_from_request_xml(InfAdoptedSession* session, xmlNodePtr xml, GError** error) { InfUserTable* user_table; InfUser* user; guint user_id; user_table = inf_session_get_user_table(INF_SESSION(session)); if(!inf_xml_util_get_attribute_uint_required(xml, "user", &user_id, error)) return FALSE; /* User ID 0 means no user */ if(user_id == 0) return NULL; user = inf_user_table_lookup_user_by_id(user_table, user_id); if(user == NULL) { g_set_error( error, inf_adopted_session_error_quark, INF_ADOPTED_SESSION_ERROR_NO_SUCH_USER, _("No such user with user ID '%u'"), user_id ); return NULL; } g_assert(INF_ADOPTED_IS_USER(user)); return INF_ADOPTED_USER(user); }
static gboolean infc_session_proxy_handle_request_failed(InfcSessionProxy* proxy, InfXmlConnection* connection, xmlNodePtr xml, GError** error) { InfcSessionProxyPrivate* priv; InfcSessionProxyClass* proxy_class; xmlChar* domain; gboolean has_code; guint code; GError* req_error; InfcRequest* request; priv = INFC_SESSION_PROXY_PRIVATE(proxy); proxy_class = INFC_SESSION_PROXY_GET_CLASS(proxy); has_code = inf_xml_util_get_attribute_uint_required( xml, "code", &code, error ); if(has_code == FALSE) return FALSE; domain = inf_xml_util_get_attribute_required(xml, "domain", error); if(domain == NULL) return FALSE; req_error = NULL; request = infc_request_manager_get_request_by_xml_required( priv->request_manager, NULL, xml, error ); if(request == NULL) return FALSE; g_assert(proxy_class->translate_error != NULL); /* TODO: Add a GError* paramater to translate_error so that an error * can be reported if the error could not be translated. */ req_error = proxy_class->translate_error( proxy, g_quark_from_string((const gchar*)domain), code ); infc_request_manager_fail_request( priv->request_manager, request, req_error ); g_error_free(req_error); xmlFree(domain); return TRUE; }
static gboolean perform_test(guint max_total_log_size, InfTextChunk* initial, GSList* users, GSList* requests, GError** error) { InfTextBuffer* buffer; InfCommunicationManager* manager; InfIo* io; InfTextSession* session; InfAdoptedAlgorithm* algorithm; InfUserTable* user_table; InfTextUser* user; gchar* user_name; GSList* item; xmlNodePtr request; gboolean result; GError* local_error; guint verify_user_id; InfAdoptedUser* verify_user; guint verify_log_size; gint verify_can_undo; gint verify_can_redo; InfAdoptedRequestLog* log; guint log_size; buffer = INF_TEXT_BUFFER(inf_text_default_buffer_new("UTF-8")); inf_text_buffer_insert_chunk(buffer, 0, initial, NULL); manager = inf_communication_manager_new(); io = INF_IO(inf_standalone_io_new()); user_table = inf_user_table_new(); local_error = NULL; for(item = users; item != NULL; item = g_slist_next(item)) { user_name = g_strdup_printf("User_%u", GPOINTER_TO_UINT(item->data)); user = INF_TEXT_USER( g_object_new( INF_TEXT_TYPE_USER, "id", GPOINTER_TO_UINT(item->data), "name", user_name, "status", INF_USER_ACTIVE, "flags", 0, NULL ) ); g_free(user_name); inf_user_table_add_user(user_table, INF_USER(user)); g_object_unref(user); } session = INF_TEXT_SESSION( g_object_new( INF_TEXT_TYPE_SESSION, "communication-manager", manager, "buffer", buffer, "io", io, "user_table", user_table, "max-total-log-size", max_total_log_size, NULL ) ); algorithm = inf_adopted_session_get_algorithm(INF_ADOPTED_SESSION(session)); g_object_unref(io); g_object_unref(manager); g_object_unref(user_table); g_object_unref(buffer); for(item = requests; item != NULL; item = item->next) { request = (xmlNodePtr)item->data; if(strcmp((const char*)request->name, "request") == 0) { /* Request */ result = inf_communication_object_received( INF_COMMUNICATION_OBJECT(session), NULL, request, &local_error ); if(local_error != NULL) goto fail; } else { /* TODO: Make an extra function out of this: */ /* Verify */ result = inf_xml_util_get_attribute_uint_required( request, "user", &verify_user_id, &local_error ); if(result == FALSE) goto fail; verify_user = INF_ADOPTED_USER( inf_user_table_lookup_user_by_id(user_table, verify_user_id) ); if(verify_user == NULL) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_USER_UNAVAILABLE, "User ID '%u' not available", verify_user_id ); goto fail; } result = inf_xml_util_get_attribute_uint( request, "log-size", &verify_log_size, &local_error ); if(local_error) goto fail; if(result) { log = inf_adopted_user_get_request_log(INF_ADOPTED_USER(verify_user)); log_size = inf_adopted_request_log_get_end(log) - inf_adopted_request_log_get_begin(log); if(verify_log_size != log_size) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_VERIFY_FAILED, "Log size does not match; got %u, but expected %u", log_size, verify_log_size ); goto fail; } } result = inf_xml_util_get_attribute_int( request, "can-undo", &verify_can_undo, &local_error ); if(local_error) goto fail; if(result) { result = inf_adopted_algorithm_can_undo(algorithm, verify_user); if(result != verify_can_undo) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_VERIFY_FAILED, "can-undo does not match; got %d, but expected %d", (guint)result, verify_can_undo ); goto fail; } } result = inf_xml_util_get_attribute_int( request, "can-redo", &verify_can_redo, &local_error ); if(local_error) goto fail; if(result) { result = inf_adopted_algorithm_can_redo(algorithm, verify_user); if(result != verify_can_redo) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_VERIFY_FAILED, "can-redo does not match; got %d, but expected %d", (guint)result, verify_can_redo ); goto fail; } } } } g_object_unref(session); return TRUE; fail: g_object_unref(session); if(local_error) g_propagate_error(error, local_error); return FALSE; }
static void foreach_test_func(const gchar* testfile, gpointer user_data) { test_result* result; xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; GSList* requests; InfTextChunk* initial; GSList* users; guint max_total_log_size; GError* error; gboolean res; /* Only process XML files, not the Makefiles or other stuff */ if(!g_str_has_suffix(testfile, ".xml")) return; result = (test_result*)user_data; doc = xmlParseFile(testfile); requests = NULL; initial = NULL; users = NULL; max_total_log_size = 0; error = NULL; printf("%s... ", testfile); fflush(stdout); ++ result->total; if(doc != NULL) { root = xmlDocGetRootElement(doc); for(child = root->children; child != NULL; child = child->next) { if(child->type != XML_ELEMENT_NODE) continue; if(strcmp((const char*)child->name, "log") == 0) { res = inf_xml_util_get_attribute_uint_required( child, "size", &max_total_log_size, &error ); if(!res) break; } else if(strcmp((const char*)child->name, "initial-buffer") == 0) { if(initial != NULL) inf_text_chunk_free(initial); initial = inf_test_util_parse_buffer(child, &error); if(initial == NULL) break; } else if(strcmp((const char*)child->name, "user") == 0) { if(inf_test_util_parse_user(child, &users, &error) == FALSE) break; } else if(strcmp((const char*)child->name, "request") == 0 || strcmp((const char*)child->name, "verify") == 0) { requests = g_slist_prepend(requests, child); } else { g_set_error( &error, inf_test_util_parse_error_quark(), INF_TEST_UTIL_PARSE_ERROR_UNEXPECTED_NODE, "Node '%s' unexpected", (const gchar*)child->name ); break; } } if(error != NULL) { printf("Failed to parse: %s\n", error->message); g_error_free(error); xmlFreeDoc(doc); g_slist_free(requests); if(initial != NULL) inf_text_chunk_free(initial); g_slist_free(users); } else { g_assert(initial != NULL); requests = g_slist_reverse(requests); if(perform_test(max_total_log_size, initial, users, requests, &error) == TRUE) { ++ result->passed; printf("OK\n"); } else { printf("FAILED (%s)\n", error->message); g_error_free(error); } xmlFreeDoc(doc); g_slist_free(requests); inf_text_chunk_free(initial); g_slist_free(users); } } }
static gboolean infd_note_plugin_text_read_user(InfUserTable* user_table, xmlNodePtr node, GError** error) { guint id; gdouble hue; xmlChar* name; gboolean result; InfUser* user; if(!inf_xml_util_get_attribute_uint_required(node, "id", &id, error)) return FALSE; if(!inf_xml_util_get_attribute_double_required(node, "hue", &hue, error)) return FALSE; name = inf_xml_util_get_attribute_required(node, "name", error); if(name == NULL) return FALSE; if(inf_user_table_lookup_user_by_id(user_table, id) != NULL) { g_set_error( error, g_quark_from_static_string("INF_NOTE_PLUGIN_TEXT_ERROR"), INFD_NOTE_PLUGIN_TEXT_ERROR_USER_EXISTS, "User with ID %u exists already", id ); result = FALSE; } else { if(inf_user_table_lookup_user_by_name(user_table, (const gchar*)name)) { g_set_error( error, g_quark_from_static_string("INF_NOTE_PLUGIN_TEXT_ERROR"), INFD_NOTE_PLUGIN_TEXT_ERROR_USER_EXISTS, "User with name `%s' exists already", (const gchar*)name ); result = FALSE; } else { user = INF_USER( g_object_new( INF_TEXT_TYPE_USER, "id", id, "name", name, "hue", hue, NULL ) ); inf_user_table_add_user(user_table, user); g_object_unref(user); result = TRUE; } } xmlFree(name); return result; }
static gboolean infd_note_plugin_text_read_buffer(InfTextBuffer* buffer, InfUserTable* user_table, xmlNodePtr node, GError** error) { xmlNodePtr child; guint author; gchar* content; gboolean result; gboolean res; InfUser* user; gsize bytes; guint chars; g_assert(inf_text_buffer_get_length(buffer) == 0); for(child = node->children; child != NULL; child = child->next) { if(child->type != XML_ELEMENT_NODE) continue; if(strcmp((const gchar*)child->name, "segment") == 0) { res = inf_xml_util_get_attribute_uint_required( child, "author", &author, error ); if(res == FALSE) { result = FALSE; break; } if(author != 0) { user = inf_user_table_lookup_user_by_id(user_table, author); if(user == NULL) { g_set_error( error, g_quark_from_static_string("INF_NOTE_PLUGIN_TEXT_ERROR"), INFD_NOTE_PLUGIN_TEXT_ERROR_NO_SUCH_USER, "User with ID %u does not exist", author ); result = FALSE; break; } } else { user = NULL; } content = inf_xml_util_get_child_text(child, &bytes, &chars, error); if(!content) { result = FALSE; break; } if(*content != '\0') { /* TODO: Use inf_text_buffer_append when we have it */ inf_text_buffer_insert_text( buffer, inf_text_buffer_get_length(buffer), content, bytes, chars, user ); } g_free(content); } else { infd_note_plugin_text_session_unexpected_node(child, error); result = FALSE; break; } } if(child == NULL) result = TRUE; return result; }