*** /dev/null Sat Nov 23 01:07:30 2024
--- - Sat Nov 23 01:07:33 2024
***************
*** 0 ****
--- 1,914 ----
+ /*
+ * XDS - OSSP Extensible Data Serialization Library Copyright (c) 2001 The
+ * OSSP Project (http://www.ossp.org/) Copyright (c) 2001 Cable & Wireless
+ * Deutschland (http://www.cw.com/de/)
+ *
+ * This file is part of OSSP XDS, an extensible data serialization library
+ * which can be found at http://www.ossp.com/pkg/xds/.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE. */
+
+ #include <string.h>
+ #include <errno.h>
+ #include <stdio.h>
+ #include "xds_p.h"
+
+ #ifdef XDS_TEST_XDS_CORE
+
+ int main()
+ {
+ xds_t *ctx[50];
+ size_t i;
+
+ /* Open a bunch of contextes and close them again. */
+
+ for (i = 0; i < sizeof (ctx) / sizeof (xds_t *); ++i) {
+ if (i % 2 == 0)
+ ctx[i] = xds_init(XDS_ENCODE);
+ else
+ ctx[i] = xds_init(XDS_DECODE);
+
+ if (ctx[i] == 0) {
+ printf("Failed to initialize xds context: i = %d\n", i);
+ return 1;
+ }
+ }
+
+ for (i = 0; i < sizeof (ctx) / sizeof (xds_t *); ++i)
+ xds_destroy(ctx[i]);
+
+ #ifdef NDEBUG
+ /* Check how the library deals with errorneous arguments. */
+
+ if (xds_init((xds_mode_t) 42) != NULL || errno != EINVAL) {
+ printf
+ ("Called xds_init() with invalid mode but didn't get EINVAL.\n");
+ return 1;
+ }
+
+ /* Call xds_destroy() with an invalid context and see whether we survive
+ * that. */
+
+ xds_destroy(NULL);
+ #endif
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_CORE */
+
+ #ifdef XDS_TEST_XDS_FIND_ENGINE
+
+ int main()
+ {
+ const engine_map_t engines[] = {
+ {"alan", NULL, 0},
+ {"berta", NULL, 0},
+ {"caesar", NULL, 0},
+ {"doris", NULL, 0},
+ {"egon", NULL, 0},
+ {"franziska", NULL, 0},
+ {"gudrun", NULL, 0},
+ {"heinz", NULL, 0},
+ {"igor", NULL, 0},
+ {"jamila", NULL, 0},
+ {"karin", NULL, 0},
+ {"louis", NULL, 0},
+ };
+ size_t engines_len = sizeof (engines) / sizeof (engine_map_t);
+ size_t pos;
+ size_t i;
+
+ /* Does xds_find_engine handle an empty array? */
+
+ if (xds_find_engine(engines, 0, "whatever", &pos)) {
+ printf
+ ("xds_find_engine() said 'whatever' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != 0) {
+ printf
+ ("xds_find_engine() would insert 'whatever' at position %d, but 0 is correct.\n",
+ pos);
+ exit(1);
+ }
+
+ /* Search for every single entry in the array and check the results. */
+
+ for (i = 0; i < engines_len; ++i) {
+ if (!xds_find_engine(engines, engines_len, engines[i].name, &pos)) {
+ printf
+ ("xds_find_engine() said '%s' wouldn't be in the array, but that's wrong.\n",
+ engines[i].name);
+ exit(1);
+ }
+ if (pos != i) {
+ printf
+ ("xds_find_engine() would insert '%s' at position %d, but %d is correct.\n",
+ engines[i].name, pos, i);
+ exit(1);
+ }
+ }
+
+ /* Search for non-existing name that would be inserted at the first
+ * position. */
+
+ if (xds_find_engine(engines, engines_len, "aaron", &pos)) {
+ printf
+ ("xds_find_engine() said 'aaron' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != 0) {
+ printf
+ ("xds_find_engine() would insert 'aaron' at position %d, but 0 is correct.\n",
+ pos);
+ exit(1);
+ }
+
+ /* Search for non-existing name that would be inserted at last position. */
+
+ if (xds_find_engine(engines, engines_len, "zerberos", &pos)) {
+ printf
+ ("xds_find_engine() said 'zerberos' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != engines_len) {
+ printf
+ ("xds_find_engine() would insert 'zerberos' at position %d, but %d is correct.\n",
+ pos, engines_len);
+ exit(1);
+ }
+
+ /* Search for non-existing names that would be inserted at random
+ * positions. */
+
+ if (xds_find_engine(engines, engines_len, "balthasar", &pos)) {
+ printf
+ ("xds_find_engine() said 'balthasar' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != 1) {
+ printf
+ ("xds_find_engine() would insert 'balthasar' at position %d, but 1 is correct.\n",
+ pos);
+ exit(1);
+ }
+
+ if (xds_find_engine(engines, engines_len, "bulli", &pos)) {
+ printf
+ ("xds_find_engine() said 'bulli' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != 2) {
+ printf
+ ("xds_find_engine() would insert 'bulli' at position %d, but 2 is correct.\n",
+ pos);
+ exit(1);
+ }
+
+ if (xds_find_engine(engines, engines_len, "hildegard", &pos)) {
+ printf
+ ("xds_find_engine() said 'hildegard' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != 8) {
+ printf
+ ("xds_find_engine() would insert 'hildegard' at position %d, but 8 is correct.\n",
+ pos);
+ exit(1);
+ }
+
+ if (xds_find_engine(engines, engines_len, "harald", &pos)) {
+ printf
+ ("xds_find_engine() said 'harald' would be in the array, but that's wrong.\n");
+ exit(1);
+ }
+ if (pos != 7) {
+ printf
+ ("xds_find_engine() would insert 'harald' at position %d, but 7 is correct.\n",
+ pos);
+ exit(1);
+ }
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_FIND_ENGINE */
+
+ #ifdef XDS_TEST_XDS_REGISTER
+
+ static int dummy_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ return 0;
+ }
+
+ int main()
+ {
+ const char *test_names[] = {
+ "foo",
+ "bar",
+ "zarah",
+ "caesar",
+ "claus",
+ "heinz",
+ };
+ size_t test_names_len = sizeof (test_names) / sizeof (char *);
+ xds_t *xds;
+ size_t i;
+
+ /* Create context. */
+
+ xds = xds_init(XDS_ENCODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+
+ /* Register the dummy callback under an invalid name to see whether the
+ * routine fails correctly. */
+
+ if (xds_register(xds, "abcdefh1230#", &dummy_engine, NULL) !=
+ XDS_ERR_INVALID_ARG) {
+ printf
+ ("xds_register() illegally accepted an invalid name for the engine.\n");
+ return 1;
+ }
+
+ /* Register the dummy callback under multiple names. */
+
+ for (i = 0; i < test_names_len; ++i) {
+ if (xds_register(xds, test_names[i], &dummy_engine, NULL) != XDS_OK) {
+ printf("Failed to register engine for '%s'.\n", test_names[i]);
+ return 1;
+ }
+ }
+
+ /* Register the callback again, overwriting an existing entry. */
+
+ if (xds_register(xds, "claus", &dummy_engine, NULL) != XDS_OK) {
+ printf("Failed to re-register engine for 'claus'.\n");
+ return 1;
+ }
+
+ /* Ensure that everything is in alphabetical order. */
+
+ for (i = 1; i < xds->engines_len; ++i) {
+ assert(xds->engines[i - 1].name != NULL);
+ assert(xds->engines[i].name != NULL);
+ if (strcmp(xds->engines[i - 1].name, xds->engines[i].name) >= 0) {
+ printf("xds->engines is not in alphabetical order!\n");
+ exit(1);
+ }
+ }
+
+ /* Try to remove an unknown entry. */
+
+ if (xds_unregister(xds, "abacadabra") != XDS_ERR_UNKNOWN_ENGINE) {
+ printf
+ ("xds_unregister() succeeded at removing 'abacadabra' even though it is not there.\n");
+ exit(1);
+ }
+
+ /* Remove an entry from the middle. */
+
+ if (xds_unregister(xds, test_names[test_names_len / 2]) != XDS_OK) {
+ printf("xds_unregister() failed to remove '%s'.\n",
+ test_names[test_names_len / 2]);
+ exit(1);
+ }
+
+ /* Remove the last entry. */
+
+ assert(test_names_len > 0);
+ if (xds_unregister(xds, test_names[test_names_len - 1]) != XDS_OK) {
+ printf("xds_unregister() failed to remove '%s'.\n",
+ test_names[test_names_len - 1]);
+ exit(1);
+ }
+
+ /* Remove the first entry. */
+
+ if (xds_unregister(xds, test_names[0]) != XDS_OK) {
+ printf("xds_unregister() failed to remove '%s'.\n", test_names[0]);
+ exit(1);
+ }
+
+ /* Clean up. */
+
+ xds_destroy(xds);
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_REGISTER */
+
+ #ifdef XDS_TEST_XDS_SETBUFFER
+
+ static int dummy_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ assert(xds != NULL);
+ assert(buffer != NULL);
+ assert(buffer_size != 0);
+ assert(used_buffer_size != NULL);
+ assert(args != NULL);
+ if (buffer_size < 64)
+ return XDS_ERR_OVERFLOW;
+ else
+ *used_buffer_size = 64;
+ memset(buffer, 'a', 64);
+ return XDS_OK;
+ }
+
+ int main()
+ {
+ xds_t *xds;
+ char *buffer;
+ size_t buffer_size;
+
+ /* Create XDS context. */
+
+ xds = xds_init(XDS_ENCODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+
+ /* Register the callback. */
+
+ if (xds_register(xds, "dummy", &dummy_engine, NULL) != XDS_OK) {
+ printf("Failed to register my encoding engine.\n");
+ return 1;
+ }
+
+ /* Give the library a buffer of 32 byte, call the engine once, get the
+ * buffer back and see whether it has been enlarged or not. */
+
+ buffer_size = 32;
+ buffer = malloc(buffer_size);
+ if (buffer == NULL) {
+ printf("Failed to allocate my memory.\n");
+ return 1;
+ }
+ if (xds_setbuffer(xds, XDS_GIFT, buffer, buffer_size) != XDS_OK) {
+ printf("xds_setbuffer() failed!\n");
+ return 1;
+ }
+ if (xds_encode(xds, "dummy") != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (xds_getbuffer(xds, XDS_GIFT, (void **)&buffer, &buffer_size) !=
+ XDS_OK) {
+ printf("xds_getbuffer() failed!\n");
+ return 1;
+ }
+ if (buffer_size < 64) {
+ printf
+ ("xds_encode() did not enlarge the buffer after processing the callback\n");
+ printf("even though all capacity was used up!\n");
+ return 1;
+ }
+
+ /* Loan the library a buffer we own, call the engine once to exceed the
+ * buffer's capacity and check, whether the library returns the correct
+ * error code. */
+
+ buffer = malloc(32);
+ if (buffer == NULL) {
+ printf("Failed to allocate my memory.\n");
+ return 1;
+ }
+ buffer_size = 32;
+ if (xds_setbuffer(xds, XDS_LOAN, buffer, buffer_size) != XDS_OK) {
+ printf("xds_setbuffer() failed!\n");
+ return 1;
+ }
+ if (xds_encode(xds, "dummy") != XDS_ERR_OVERFLOW) {
+ printf("xds_encode() was supposed to fail with XDS_ERR_OVERFLOW!\n");
+ return 1;
+ }
+ free(buffer);
+
+ /* Clean up. */
+
+ xds_destroy(xds);
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_SETBUFFER */
+
+ #ifdef XDS_TEST_XDS_GETBUFFER
+
+ static int dummy_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ if (buffer_size < 6)
+ return XDS_ERR_OVERFLOW;
+ else
+ *used_buffer_size = 6;
+
+ memmove(buffer, "Hallo!", 6);
+ return XDS_OK;
+ }
+
+ int main()
+ {
+ xds_t *xds;
+ char *old;
+ size_t old_len;
+ char *new;
+ size_t new_len;
+
+ /* Create XDS context. */
+
+ xds = xds_init(XDS_ENCODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+
+ /* Register the dummy callback under multiple names. */
+
+ if (xds_register(xds, "text", &dummy_engine, (void *)42) != XDS_OK) {
+ printf("Failed to register my encoding engine.\n");
+ return 1;
+ }
+
+ /* Encode something, then flush the buffer by calling xds_getbuffer(),
+ * then encode something new and verify that the old buffer hasn't ben
+ * overwritten and that the new one contains the correct string. */
+
+ if (xds_encode(xds, "text text") != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (xds_getbuffer(xds, XDS_GIFT, (void **)&old, &old_len) != XDS_OK) {
+ printf("xds_getbuffer() failed for the first buffer!\n");
+ return 1;
+ }
+ if (xds_encode(xds, "text") != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (xds_getbuffer(xds, XDS_GIFT, (void **)&new, &new_len) != XDS_OK) {
+ printf("xds_getbuffer() failed for the second buffer!\n");
+ return 1;
+ }
+ if ((memcmp(old, "Hallo!Hallo!", 12) != 0 || old_len != 12) &&
+ (memcmp(new, "Hallo!", 6) != 0 || new_len != 6)) {
+ printf("xds_encode() did not yield the expected result.\n");
+ return 1;
+ }
+ free(old);
+ free(new);
+
+ /* Encode somthing, then get the buffer via XDS_LOAN and verify the
+ * contents. Encode something new and compare the new content with what
+ * we expect. */
+
+ if (xds_encode(xds, "text text") != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (xds_getbuffer(xds, XDS_LOAN, (void **)&old, &old_len) != XDS_OK) {
+ printf("xds_getbuffer() failed for the first buffer!\n");
+ return 1;
+ }
+ if (memcmp(old, "Hallo!Hallo!", 12) != 0 || old_len != 12) {
+ printf("xds_encode() did not yield the expected result.\n");
+ return 1;
+ }
+ if (xds_encode(xds, "text") != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (xds_getbuffer(xds, XDS_LOAN, (void **)&new, &new_len) != XDS_OK) {
+ printf("xds_getbuffer() failed for the second buffer!\n");
+ return 1;
+ }
+ if (old != new) {
+ printf
+ ("xds_encode() allocated a new buffer even though we used XDS_LOAN.\n");
+ return 1;
+ }
+ if (memcmp(new, "Hallo!", 6) != 0 || new_len != 6) {
+ printf("xds_encode() did not yield the expected result.\n");
+ return 1;
+ }
+
+ /* Clean up. */
+
+ xds_destroy(xds);
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_GETBUFFER */
+
+ #ifdef XDS_TEST_XDS_ENCODE
+
+ static int dummy_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ if (xds == NULL) {
+ printf("XDS context isn't passed through to registered engine.\n");
+ exit(1);
+ }
+ if (engine_context != (void *)42) {
+ printf("Engine context isn't passed through to registered engine.\n");
+ exit(1);
+ }
+ if (buffer == NULL) {
+ printf("Buffer passed to engine is NULL.\n");
+ exit(1);
+ }
+ if (buffer_size == 0) {
+ printf("buffer_size passed to engine is zero!\n");
+ exit(1);
+ }
+ if (used_buffer_size == NULL) {
+ printf("used_buffer_size pointer passed to engine is NULL!\n");
+ exit(1);
+ }
+ if (args == NULL) {
+ printf("args pointer passed to engine is NULL!\n");
+ exit(1);
+ }
+ *used_buffer_size = 6;
+ if (buffer_size < 6)
+ return XDS_ERR_OVERFLOW;
+ memmove(buffer, "Hallo ", 6);
+ return XDS_OK;
+ }
+
+ int main()
+ {
+ xds_t *xds;
+
+ /* Create XDS context. */
+
+ xds = xds_init(XDS_ENCODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+
+ /* Register the dummy callback under multiple names. */
+
+ if (xds_register(xds, "int", &dummy_engine, (void *)42) != XDS_OK ||
+ xds_register(xds, "float", &dummy_engine, (void *)42) != XDS_OK ||
+ xds_register(xds, "double", &dummy_engine, (void *)42) != XDS_OK ||
+ xds_register(xds, "text", &dummy_engine, (void *)42) != XDS_OK) {
+ printf("Failed to register my encoding engines.\n");
+ return 1;
+ }
+
+ /* Let's go and encode something. */
+
+ if (xds_encode(xds, "int:text double double float") != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (memcmp(xds->buffer, "Hallo Hallo Hallo Hallo Hallo ", 30) != 0) {
+ printf("xds_encode() did not yield the expected result.\n");
+ return 1;
+ }
+
+ /* Clean up. */
+
+ xds_destroy(xds);
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_ENCODE */
+
+ #ifdef XDS_TEST_XDS_DECODE
+
+ static int dummy_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ if (xds == NULL) {
+ printf("XDS context isn't passed through to registered engine.\n");
+ exit(1);
+ }
+ if (engine_context != (void *)42) {
+ printf("Engine context isn't passed through to registered engine.\n");
+ exit(1);
+ }
+ if (buffer == NULL) {
+ printf("Buffer passed to engine is NULL.\n");
+ exit(1);
+ }
+ if (buffer_size == 0) {
+ printf("Buffer size passed to engine is zero!\n");
+ exit(1);
+ }
+ if (used_buffer_size == NULL) {
+ printf("used_buffer_size passed to engine is zero!\n");
+ exit(1);
+ }
+ if (args == NULL) {
+ printf("args pointer passed to engine is NULL!\n");
+ exit(1);
+ }
+ if (buffer_size < 6) {
+ printf("The buffer is too small; can't verify my encoded string.\n");
+ exit(1);
+ }
+ if (memcmp(buffer, "Hallo!", 6) != 0) {
+ printf
+ ("The contents of the decode buffer are not what we expected.\n");
+ exit(1);
+ }
+ *used_buffer_size = 6;
+ return XDS_OK;
+ }
+
+ int main()
+ {
+ xds_t *xds;
+ char buffer[] = "Hallo!Hallo!Hallo!";
+
+ /* Create XDS context. */
+
+ xds = xds_init(XDS_DECODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+
+ /* Register the dummy callback under multiple names. */
+
+ if (xds_register(xds, "text", &dummy_engine, (void *)42) != XDS_OK) {
+ printf("Failed to register my decoding engines.\n");
+ return 1;
+ }
+
+ /* Decode the buffer and have the callback report when something is
+ * wrong. */
+
+ if (xds_setbuffer(xds, XDS_LOAN, buffer, sizeof (buffer) - 1) != XDS_OK) {
+ printf("xds_decode() failed!");
+ return 1;
+ }
+
+ if (xds_decode(xds, "text::text text") != XDS_OK) {
+ printf("xds_decode() failed!");
+ return 1;
+ }
+
+ /* Clean up. */
+
+ xds_destroy(xds);
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_DECODE */
+
+ #ifdef XDS_TEST_XDS_ENGINE_RESTART
+
+ static int dummy_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ if (xds == NULL) {
+ printf("XDS context isn't passed through to registered engine.\n");
+ exit(1);
+ }
+ if (engine_context != (void *)42) {
+ printf("Engine context isn't passed through to registered engine.\n");
+ exit(1);
+ }
+ if (buffer == NULL) {
+ printf("Buffer passed to engine is NULL.\n");
+ exit(1);
+ }
+ if (buffer_size == 0) {
+ printf("Buffer size passed to engine is zero!\n");
+ exit(1);
+ }
+ if (used_buffer_size == NULL) {
+ printf("used_buffer_size pointer passed to engine is NULL!\n");
+ exit(1);
+ }
+ if (args == NULL) {
+ printf("args pointer passed to engine is NULL!\n");
+ exit(1);
+ }
+ if (va_arg(*args, int) != 42) {
+ printf("The varadic argument is not what the engine expected!\n");
+ exit(1);
+ }
+ if (buffer_size < 64)
+ return XDS_ERR_OVERFLOW;
+ else
+ *used_buffer_size = 64;
+ return XDS_OK;
+ }
+
+ int main()
+ {
+ xds_t *xds;
+ char *buffer;
+ size_t buffer_size;
+
+ /* Create an XDS context and set a buffer that's too small for the first
+ * encode() call. Then call encode() with two parameters: the one the
+ * engine is expecting and a different one after that. The engine will
+ * complain if it sees the second value -- what would mean that the args
+ * parameter was not resetted to the original value before the engine is
+ * restarted after buffer enlargement. */
+
+ xds = xds_init(XDS_ENCODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+ if (xds_register(xds, "int", &dummy_engine, (void *)42) != XDS_OK) {
+ printf("Failed to register my encoding engines.\n");
+ return 1;
+ }
+ buffer = malloc(32);
+ if (buffer == NULL) {
+ printf("malloc() failed!\n");
+ return 1;
+ }
+ buffer_size = 32;
+ if (xds_setbuffer(xds, XDS_GIFT, buffer, buffer_size) != XDS_OK) {
+ printf("xds_setbuffer() failed!\n");
+ return 1;
+ }
+ if (xds_encode(xds, "int", 42, 13) != XDS_OK) {
+ printf("xds_encode() failed!");
+ return 1;
+ }
+ xds_destroy(xds);
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_ENGINE_RESTART */
+
+ #ifdef XDS_TEST_XDS_MYSTRUCT
+
+ struct mystruct {
+ xds_int32_t small;
+ xds_uint32_t positive;
+ };
+
+ static int encode_mystruct_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ struct mystruct *ms;
+
+ assert(xds != NULL);
+ assert(buffer != NULL);
+ assert(buffer_size != 0);
+ assert(used_buffer_size != NULL);
+ assert(args != NULL);
+
+ ms = va_arg(*args, struct mystruct *);
+ return xds_encode(xds, "int32 uint32", ms->small, ms->positive);
+ }
+
+ static int decode_mystruct_engine(xds_t * xds, void *engine_context,
+ void *buffer, size_t buffer_size,
+ size_t * used_buffer_size, va_list * args)
+ {
+ struct mystruct *ms;
+
+ assert(xds != NULL);
+ assert(buffer != NULL);
+ assert(buffer_size != 0);
+ assert(used_buffer_size != NULL);
+ assert(args != NULL);
+
+ ms = va_arg(*args, struct mystruct *);
+ return xds_decode(xds, "int32 uint32", &(ms->small), &(ms->positive));
+ }
+
+ int main()
+ {
+ xds_t *xds;
+ char *buffer;
+ size_t buffer_size;
+
+ struct mystruct ms, new_ms;
+ ms.small = -0x1234567;
+ ms.positive = 42;
+
+ /* Encode our copy of mystruct using our encoding callback. Then get a
+ * the buffer and destroy the context again. */
+
+ xds = xds_init(XDS_ENCODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+ if (xds_register(xds, "mystruct", &encode_mystruct_engine, NULL) != XDS_OK
+ || xds_register(xds, "int32", &xdr_encode_int32, NULL) != XDS_OK
+ || xds_register(xds, "uint32", &xdr_encode_uint32, NULL) != XDS_OK) {
+ printf("Failed to register my encoding engines.\n");
+ return 1;
+ }
+ buffer_size = 4;
+ buffer = malloc(buffer_size);
+ if (buffer == NULL) {
+ printf("Failed to allocate memory for buffer.\n");
+ return 1;
+ }
+ if (xds_setbuffer(xds, XDS_GIFT, buffer, buffer_size) != XDS_OK) {
+ printf("xds_setbuffer() failed!\n");
+ return 1;
+ }
+ if (xds_encode(xds, "mystruct", &ms) != XDS_OK) {
+ printf("xds_encode() failed!\n");
+ return 1;
+ }
+ if (xds->buffer_capacity <= buffer_size) {
+ printf("Buffer should have been enlarged after xds_encode()!\n");
+ return 1;
+ }
+ if (xds_getbuffer(xds, XDS_GIFT, (void **)&buffer, &buffer_size) !=
+ XDS_OK) {
+ printf("xds_getbuffer() failed!\n");
+ return 1;
+ }
+ xds_destroy(xds);
+ printf("The encoded representation is %u bytes long.\n", buffer_size);
+
+ /* Now create a decoding context and decode the whole thing again. */
+
+ xds = xds_init(XDS_DECODE);
+ if (xds == NULL) {
+ printf("Failed to initialize XDS context.\n");
+ return 1;
+ }
+ if (xds_register(xds, "mystruct", &decode_mystruct_engine, NULL) != XDS_OK
+ || xds_register(xds, "int32", &xdr_decode_int32, NULL) != XDS_OK
+ || xds_register(xds, "uint32", &xdr_decode_uint32, NULL) != XDS_OK) {
+ printf("Failed to register my decoding engines.\n");
+ return 1;
+ }
+ if (xds_setbuffer(xds, XDS_GIFT, buffer, buffer_size) != XDS_OK) {
+ printf("xds_setbuffer() failed!\n");
+ return 1;
+ }
+ if (xds_decode(xds, "mystruct", &new_ms) != XDS_OK) {
+ printf("xds_decode() failed!\n");
+ return 1;
+ }
+ xds_destroy(xds);
+
+ /* Both structures must be identical. */
+
+ if (ms.small != new_ms.small
+ || ms.positive != new_ms.positive) {
+ printf("Decoded data does not match the original!\n");
+ return 1;
+ }
+
+ /* Everything went fine. */
+
+ return 0;
+ }
+
+ #endif /* XDS_TEST_XDS_MYSTRUCT */
|