--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "xmlrpc_config.h"
+
+#include "xmlrpc-c/base.h"
+
+#include "test.h"
+#include "xml_data.h"
+#include "serialize.h"
+
+
+
+static void
+test_serialize_basic(void) {
+
+ xmlrpc_env env;
+ xmlrpc_value * v;
+ xmlrpc_mem_block *output;
+ size_t size;
+
+ xmlrpc_env_init(&env);
+
+ /* Build a nice, messy value to serialize. We should attempt to use
+ ** use every data type except double (which doesn't serialize in a
+ ** portable manner. */
+ v = xmlrpc_build_value(&env, "(iibbs68())",
+ (xmlrpc_int32) INT_MAX, (xmlrpc_int32) INT_MIN,
+ (xmlrpc_bool) 0, (xmlrpc_bool) 1,
+ "Hello, world! <&>",
+ "base64 data", (size_t) 11,
+ "19980717T14:08:55");
+ TEST_NO_FAULT(&env);
+
+ /* Serialize the value. */
+ output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
+ TEST_NO_FAULT(&env);
+ xmlrpc_serialize_value(&env, output, v);
+ TEST_NO_FAULT(&env);
+
+ /* Make sure we serialized the correct value. */
+ size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
+ TEST(size == strlen(serialized_data));
+ TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
+ serialized_data, size) == 0);
+
+ /* (Debugging code to display the value.) */
+ /* XMLRPC_TYPED_MEM_BLOCK_APPEND(char, &env, output, "\0", 1);
+ ** TEST_NO_FAULT(&env);
+ ** printf("%s\n", XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output)); */
+
+ /* Clean up our value. */
+ XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
+ xmlrpc_DECREF(v);
+
+ xmlrpc_env_clean(&env);
+}
+
+
+
+static void
+test_serialize_double(void) {
+
+ /* Test serialize of a double. */
+
+ xmlrpc_env env;
+ xmlrpc_value * v;
+ xmlrpc_mem_block *output;
+ char * result;
+ /* serialized result, as asciiz string */
+ size_t resultLength;
+ /* Length in characters of the serialized result */
+ float serializedValue;
+ char nextChar;
+ int itemsMatched;
+
+ xmlrpc_env_init(&env);
+
+ /* Build a double to serialize */
+ v = xmlrpc_build_value(&env, "d", 3.14159);
+ TEST_NO_FAULT(&env);
+
+ /* Serialize the value. */
+ output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
+ TEST_NO_FAULT(&env);
+ xmlrpc_serialize_value(&env, output, v);
+ TEST_NO_FAULT(&env);
+
+ /* Make sure we serialized the correct value. Note that because
+ doubles aren't precise, this might serialize as 3.1415899999
+ or something like that. So we check it arithmetically.
+ */
+ resultLength = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
+ result = malloc(resultLength + 1);
+
+ memcpy(result, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
+ resultLength);
+ result[resultLength] = '\0';
+
+ itemsMatched = sscanf(result,
+ "<value><double>%f</double></value>\r\n%c",
+ &serializedValue, &nextChar);
+
+ TEST(itemsMatched == 1);
+ TEST(serializedValue - 3.14159 < .000001);
+ /* We'd like to test more precision, but sscanf doesn't do doubles */
+
+ free(result);
+
+ /* Clean up our value. */
+ XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
+ xmlrpc_DECREF(v);
+
+ xmlrpc_env_clean(&env);
+}
+
+
+
+static void
+test_serialize_struct(void) {
+
+ /* Serialize a simple struct. */
+
+ char const serialized_struct[] =
+ "<value><struct>\r\n" \
+ "<member><name><&></name>\r\n" \
+ "<value><i4>10</i4></value></member>\r\n" \
+ "</struct></value>";
+
+ xmlrpc_env env;
+ xmlrpc_value * v;
+ xmlrpc_mem_block *output;
+ size_t size;
+
+ xmlrpc_env_init(&env);
+
+ v = xmlrpc_build_value(&env, "{s:i}", "<&>", (xmlrpc_int32) 10);
+ TEST_NO_FAULT(&env);
+ output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
+ TEST_NO_FAULT(&env);
+ xmlrpc_serialize_value(&env, output, v);
+ TEST_NO_FAULT(&env);
+
+ /* Make sure we serialized the correct value. */
+ size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
+ TEST(size == strlen(serialized_struct));
+ TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
+ serialized_struct, size) == 0);
+
+ /* Clean up our struct. */
+ XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
+ xmlrpc_DECREF(v);
+
+ xmlrpc_env_clean(&env);
+}
+
+
+
+static void
+test_serialize_methodResponse(void) {
+
+ /* Serialize a methodResponse. */
+
+ char const serialized_response[] =
+ XML_PROLOGUE
+ "<methodResponse>\r\n"
+ "<params>\r\n"
+ "<param><value><i4>30</i4></value></param>\r\n"
+ "</params>\r\n"
+ "</methodResponse>\r\n";
+
+ xmlrpc_env env;
+ xmlrpc_value * v;
+ xmlrpc_mem_block *output;
+ size_t size;
+
+ xmlrpc_env_init(&env);
+
+ output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
+ TEST_NO_FAULT(&env);
+ v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 30);
+ TEST_NO_FAULT(&env);
+ xmlrpc_serialize_response(&env, output, v);
+ TEST_NO_FAULT(&env);
+
+ /* Make sure we serialized the correct value. */
+ size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
+ TEST(size == strlen(serialized_response));
+ TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
+ serialized_response, size) == 0);
+
+ /* Clean up our methodResponse. */
+ xmlrpc_DECREF(v);
+ XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
+
+ xmlrpc_env_clean(&env);
+}
+
+
+
+static void
+test_serialize_methodCall(void) {
+
+ /* Serialize a methodCall. */
+
+ xmlrpc_env env;
+ xmlrpc_value * v;
+ xmlrpc_mem_block *output;
+ size_t size;
+
+ xmlrpc_env_init(&env);
+
+ output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
+ TEST_NO_FAULT(&env);
+ v = xmlrpc_build_value(&env, "(ii)", (xmlrpc_int32) 10, (xmlrpc_int32) 20);
+ TEST_NO_FAULT(&env);
+ xmlrpc_serialize_call(&env, output, "gloom&doom", v);
+ TEST_NO_FAULT(&env);
+
+ /* Make sure we serialized the correct value. */
+ size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
+ TEST(size == strlen(serialized_call));
+ TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
+ serialized_call, size) == 0);
+
+ /* Clean up our methodCall. */
+ xmlrpc_DECREF(v);
+ XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
+
+ xmlrpc_env_clean(&env);
+}
+
+
+
+static void
+test_serialize_fault(void) {
+ /* Serialize a fault. */
+
+ xmlrpc_env env;
+ xmlrpc_env fault;
+ xmlrpc_mem_block *output;
+ size_t size;
+
+ xmlrpc_env_init(&env);
+
+ output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
+ TEST_NO_FAULT(&env);
+ xmlrpc_env_init(&fault);
+ xmlrpc_env_set_fault(&fault, 6, "A fault occurred");
+ xmlrpc_serialize_fault(&env, output, &fault);
+ TEST_NO_FAULT(&env);
+
+ /* Make sure we serialized the correct value. */
+ size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
+ TEST(size == strlen(serialized_fault));
+ TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
+ serialized_fault, size) == 0);
+
+ /* Clean up our fault. */
+ xmlrpc_env_clean(&fault);
+ XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
+
+ xmlrpc_env_clean(&env);
+}
+
+
+
+void
+test_serialize(void) {
+
+ printf("Running serialize tests.");
+
+ test_serialize_basic();
+ test_serialize_double();
+ test_serialize_struct();
+ test_serialize_methodResponse();
+ test_serialize_methodCall();
+ test_serialize_fault();
+
+ printf("\n");
+ printf("Serialize tests done.\n");
+}