diff options
Diffstat (limited to 'src/raptor_stringbuffer.c')
-rw-r--r-- | src/raptor_stringbuffer.c | 902 |
1 files changed, 902 insertions, 0 deletions
diff --git a/src/raptor_stringbuffer.c b/src/raptor_stringbuffer.c new file mode 100644 index 0000000..03223c3 --- /dev/null +++ b/src/raptor_stringbuffer.c @@ -0,0 +1,902 @@ +/* -*- Mode: c; c-basic-offset: 2 -*- + * + * raptor_stringbuffer.c - Stringbuffer class for growing strings + * + * Copyright (C) 2003-2008, David Beckett http://www.dajobe.org/ + * Copyright (C) 2003-2004, University of Bristol, UK http://www.bristol.ac.uk/ + * + * This package is Free Software and part of Redland http://librdf.org/ + * + * It is licensed under the following three licenses as alternatives: + * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version + * 2. GNU General Public License (GPL) V2 or any newer version + * 3. Apache License, V2.0 or any newer version + * + * You may not use this file except in compliance with at least one of + * the above three licenses. + * + * See LICENSE.html or LICENSE.txt at the top of this package for the + * complete terms and further detail along with the license texts for + * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. + * + * + * + */ + + +#ifdef HAVE_CONFIG_H +#include <raptor_config.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <sys/types.h> + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> /* for abort() as used in errors */ +#endif + +/* Raptor includes */ +#include "raptor2.h" +#include "raptor_internal.h" + + +#ifndef STANDALONE + +struct raptor_stringbuffer_node_s +{ + struct raptor_stringbuffer_node_s* next; + unsigned char *string; + size_t length; +}; +typedef struct raptor_stringbuffer_node_s raptor_stringbuffer_node; + + +struct raptor_stringbuffer_s +{ + /* Pointing to the first item in the list of nodes */ + raptor_stringbuffer_node* head; + /* and the last */ + raptor_stringbuffer_node* tail; + + /* total length of the string */ + size_t length; + + /* frozen string if already calculated, or NULL if not present */ + unsigned char *string; +}; + + +/* prototypes for local functions */ +static int raptor_stringbuffer_append_string_common(raptor_stringbuffer* stringbuffer, const unsigned char *string, size_t length, int do_copy); + + +/* functions implementing the stringbuffer api */ + +/** + * raptor_new_stringbuffer: + * + * Create a new stringbuffer. + * + * Return value: pointer to a raptor_stringbuffer object or NULL on failure + **/ +raptor_stringbuffer* +raptor_new_stringbuffer(void) +{ + raptor_stringbuffer* sb; + + sb = RAPTOR_CALLOC(raptor_stringbuffer*, 1, sizeof(*sb)); + return sb; +} + + +/** + * raptor_free_stringbuffer: + * @stringbuffer: stringbuffer object to destroy. + * + * Destroy a stringbuffer. + * + **/ +void +raptor_free_stringbuffer(raptor_stringbuffer *stringbuffer) +{ + if(!stringbuffer) + return; + + if(stringbuffer->head) { + raptor_stringbuffer_node *node = stringbuffer->head; + + while(node) { + raptor_stringbuffer_node *next = node->next; + + if(node->string) + RAPTOR_FREE(char*, node->string); + RAPTOR_FREE(raptor_stringbuffer_node, node); + node = next; + } + } + + if(stringbuffer->string) + RAPTOR_FREE(char*, stringbuffer->string); + + RAPTOR_FREE(raptor_stringbuffer, stringbuffer); +} + + + +/** + * raptor_stringbuffer_append_string_common: + * @stringbuffer: raptor stringbuffer + * @string: string + * @length: length of string + * @do_copy: non-0 to copy the string + * + * Add a string to the stringbuffer. + * + * INTERNAL + * + * If @string is NULL or @length is 0, no work is performed. + * + * If @do_copy is non-0, the passed-in string is copied into new memory + * otherwise the stringbuffer becomes the owner of the string pointer + * and will free it when the stringbuffer is destroyed. + * + * Return value: non-0 on failure + **/ +static int +raptor_stringbuffer_append_string_common(raptor_stringbuffer* stringbuffer, + const unsigned char *string, + size_t length, + int do_copy) +{ + raptor_stringbuffer_node *node; + + if(!string || !length) + return 0; + + node = RAPTOR_MALLOC(raptor_stringbuffer_node*, sizeof(*node)); + if(!node) { + if(!do_copy) + RAPTOR_FREE(char*, string); + return 1; + } + + if(do_copy) { + /* Note this copy does not include the \0 character - not needed */ + node->string = RAPTOR_MALLOC(unsigned char*, length); + if(!node->string) { + RAPTOR_FREE(raptor_stringbuffer_node, node); + return 1; + } + memcpy(node->string, string, length); + } else + node->string = (unsigned char*)string; + node->length = length; + + + if(stringbuffer->tail) { + stringbuffer->tail->next = node; + stringbuffer->tail = node; + } else + stringbuffer->head = stringbuffer->tail = node; + node->next = NULL; + + if(stringbuffer->string) { + RAPTOR_FREE(char*, stringbuffer->string); + stringbuffer->string = NULL; + } + stringbuffer->length += length; + + return 0; +} + + + + +/** + * raptor_stringbuffer_append_counted_string: + * @stringbuffer: raptor stringbuffer + * @string: string + * @length: length of string + * @do_copy: non-0 to copy the string + * + * Add a counted string to the stringbuffer. + * + * If @string is NULL or @length is 0, no work is performed. + * + * If @do_copy is non-0, the passed-in string is copied into new memory + * otherwise the stringbuffer becomes the owner of the string pointer + * and will free it when the stringbuffer is destroyed. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_append_counted_string(raptor_stringbuffer* stringbuffer, + const unsigned char *string, size_t length, + int do_copy) +{ + if(!string || !length) + return 0; + + return raptor_stringbuffer_append_string_common(stringbuffer, string, length, do_copy); +} + + +/** + * raptor_stringbuffer_append_string: + * @stringbuffer: raptor stringbuffer + * @string: string + * @do_copy: non-0 to copy the string + * + * Add a string to the stringbuffer. + * + * If @string is NULL, no work is performed. + * + * If @do_copy is non-0, the passed-in string is copied into new memory + * otherwise the stringbuffer becomes the owner of the string pointer + * and will free it when the stringbuffer is destroyed. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_append_string(raptor_stringbuffer* stringbuffer, + const unsigned char *string, int do_copy) +{ + if(!string) + return 0; + + return raptor_stringbuffer_append_string_common(stringbuffer, string, strlen((const char*)string), do_copy); +} + + +/** + * raptor_stringbuffer_append_decimal: + * @stringbuffer: raptor stringbuffer + * @integer: integer to format as decimal and add + * + * Add an integer in decimal to the stringbuffer. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_append_decimal(raptor_stringbuffer* stringbuffer, + int integer) +{ + /* enough for 64 bit signed integer + * INT64_MAX is 9223372036854775807 (19 digits) + 1 for sign + */ + unsigned char buf[20]; + unsigned char *p; + int i = integer; + size_t length = 1; + if(integer < 0) { + length++; + i= -integer; + } + while(i /= 10) + length++; + + p = buf+length-1; + i = integer; + if(i < 0) + i= -i; + do { + *p-- = RAPTOR_GOOD_CAST(unsigned char, '0'+(i %10)); + i /= 10; + } while(i); + if(integer < 0) + *p= '-'; + + return raptor_stringbuffer_append_counted_string(stringbuffer, buf, length, 1); +} + + +/** + * raptor_stringbuffer_append_stringbuffer: + * @stringbuffer: #raptor_stringbuffer + * @append: #raptor_stringbuffer to append + * + * Add a stringbuffer to the stringbuffer. + * + * This function removes the content from the appending stringbuffer, + * making it empty and appends it to the supplied stringbuffer. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_append_stringbuffer(raptor_stringbuffer* stringbuffer, + raptor_stringbuffer* append) +{ + raptor_stringbuffer_node *node = append->head; + + if(!node) + return 0; + + /* move all append nodes to stringbuffer */ + if(stringbuffer->tail) { + stringbuffer->tail->next = node; + } else + stringbuffer->head = node; + + stringbuffer->tail = append->tail; + + /* adjust our length */ + stringbuffer->length += append->length; + if(stringbuffer->string) { + RAPTOR_FREE(char*, stringbuffer->string); + stringbuffer->string = NULL; + } + + /* zap append content */ + append->head = append->tail = NULL; + append->length = 0; + if(append->string) { + RAPTOR_FREE(char*, append->string); + append->string = NULL; + } + + return 0; +} + + + + +/** + * raptor_stringbuffer_prepend_string_common: + * @stringbuffer: raptor stringbuffer + * @string: string + * @length: length of string + * @do_copy: non-0 to copy the string + * + * Add a string to the start of a stringbuffer. + * + * INTERNAL + * + * If do_copy is non-0, the passed-in string is copied into new memory + * otherwise the stringbuffer becomes the owner of the string pointer + * and will free it when the stringbuffer is destroyed. + * + * Return value: non-0 on failure + **/ +static int +raptor_stringbuffer_prepend_string_common(raptor_stringbuffer* stringbuffer, + const unsigned char *string, size_t length, + int do_copy) +{ + raptor_stringbuffer_node *node; + + node = RAPTOR_MALLOC(raptor_stringbuffer_node*, sizeof(*node)); + if(!node) + return 1; + + if(do_copy) { + /* Note this copy does not include the \0 character - not needed */ + node->string = RAPTOR_MALLOC(unsigned char*, length); + if(!node->string) { + RAPTOR_FREE(raptor_stringbuffer_node, node); + return 1; + } + memcpy(node->string, string, length); + } else + node->string = (unsigned char*)string; + node->length = length; + + + node->next = stringbuffer->head; + if(stringbuffer->head) + stringbuffer->head = node; + else + stringbuffer->head = stringbuffer->tail = node; + + if(stringbuffer->string) { + RAPTOR_FREE(char*, stringbuffer->string); + stringbuffer->string = NULL; + } + stringbuffer->length += length; + + return 0; +} + + + + +/** + * raptor_stringbuffer_prepend_counted_string: + * @stringbuffer: raptor stringbuffer + * @string: string + * @length: length of string + * @do_copy: non-0 to copy the string + + * If do_copy is non-0, the passed-in string is copied into new memory + * otherwise the stringbuffer becomes the owner of the string pointer + * and will free it when the stringbuffer is destroyed. + * + * Add a string to the start of the stringbuffer. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_prepend_counted_string(raptor_stringbuffer* stringbuffer, + const unsigned char *string, size_t length, + int do_copy) +{ + return raptor_stringbuffer_prepend_string_common(stringbuffer, string, length, do_copy); +} + + +/** + * raptor_stringbuffer_prepend_string: + * @stringbuffer: raptor stringbuffer + * @string: string + * @do_copy: non-0 to copy the string + * + * Add a string to the start of the stringbuffer. + * + * If do_copy is non-0, the passed-in string is copied into new memory + * otherwise the stringbuffer becomes the owner of the string pointer + * and will free it when the stringbuffer is destroyed. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_prepend_string(raptor_stringbuffer* stringbuffer, + const unsigned char *string, int do_copy) +{ + return raptor_stringbuffer_prepend_string_common(stringbuffer, string, strlen((const char*)string), do_copy); +} + + +/** + * raptor_stringbuffer_length: + * @stringbuffer: raptor stringbuffer + * + * Return the stringbuffer length. + * + * Return value: size of stringbuffer + **/ +size_t +raptor_stringbuffer_length(raptor_stringbuffer* stringbuffer) +{ + return stringbuffer->length; +} + + + +/** + * raptor_stringbuffer_as_string: + * @stringbuffer: raptor stringbuffer + * + * Return the stringbuffer as a C string. + * + * Note: the return value is a to a shared string that the stringbuffer + * allocates and manages. + * + * Return value: NULL on failure or stringbuffer is empty, otherwise + * a pointer to a shared copy of the string. + **/ +unsigned char * +raptor_stringbuffer_as_string(raptor_stringbuffer* stringbuffer) +{ + raptor_stringbuffer_node *node; + unsigned char *p; + + if(!stringbuffer->length) + return NULL; + if(stringbuffer->string) + return stringbuffer->string; + + stringbuffer->string = RAPTOR_MALLOC(unsigned char*, stringbuffer->length + 1); + if(!stringbuffer->string) + return NULL; + + node = stringbuffer->head; + p = stringbuffer->string; + while(node) { + memcpy(p, node->string, node->length); + p+= node->length; + node = node->next; + } + *p='\0'; + return stringbuffer->string; +} + + +/** + * raptor_stringbuffer_copy_to_string: + * @stringbuffer: raptor stringbuffer + * @string: output string + * @length: size of output string + * + * Copy the stringbuffer into a string. + * + * Copies the underlying string to a pre-allocated buffer. The + * output string is always '\0' terminated. + * + * Return value: non-0 on failure such as stringbuffer is empty, buffer is too small + **/ +int +raptor_stringbuffer_copy_to_string(raptor_stringbuffer* stringbuffer, + unsigned char *string, size_t length) +{ + raptor_stringbuffer_node *node; + unsigned char *p; + + if(!string || length < 1) + return 1; + + if(!stringbuffer->length) + return 0; + + p = string; + for(node = stringbuffer->head; node; node = node->next) { + if(node->length > length) { + p[-1]='\0'; + return 1; + } + memcpy(p, node->string, node->length); + p+= node->length; + length-= node->length; + } + *p='\0'; + return 0; +} + + + +/** + * raptor_stringbuffer_append_hexadecimal: + * @stringbuffer: raptor stringbuffer + * @hex: integer to format + * + * Add an integer formatted in hexdecimal (base 16) to the stringbuffer. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_append_hexadecimal(raptor_stringbuffer* stringbuffer, + int hex) +{ + unsigned char buf[2]; + + if(hex < 0 || hex > 0xF) + return 1; + + *buf = RAPTOR_GOOD_CAST(unsigned char, (hex < 10) ? ('0' + hex) : ('A' + hex - 10)); + buf[1] = '\0'; + + return raptor_stringbuffer_append_counted_string(stringbuffer, buf, 1, 1); +} + + +/* RFC3986 Unreserved */ +#define IS_URI_UNRESERVED(c) ( (c >= 'A' && c <= 'F') || \ + (c >= 'a' && c <= 'f') || \ + (c >= '0' && c <= '9') || \ + (c == '-' || c == '.' || c == '_' || c == '~') ) +#define IS_URI_SAFE(c) (IS_URI_UNRESERVED(c)) + + +/** + * raptor_stringbuffer_append_uri_escaped_counted_string: + * @sb: raptor stringbuffer + * @string: string + * @length: length of string + * @space_is_plus: if non-0, escape spaces as '+' otherwise percent-encode them + * + * Add a URI-escaped version of @string to the stringbuffer. + * + * If @string is NULL or @length is 0, no work is performed. + * + * Return value: non-0 on failure + **/ +int +raptor_stringbuffer_append_uri_escaped_counted_string(raptor_stringbuffer* sb, + const char* string, + size_t length, + int space_is_plus) +{ + unsigned int i; + unsigned char buf[2]; + buf[1] = '\0'; + + if(!string || !length) + return 0; + + for(i = 0; i < length; i++) { + char c = string[i]; + if(!c) + break; + + if(IS_URI_SAFE(c)) { + *buf = RAPTOR_GOOD_CAST(unsigned char, c); + + if(raptor_stringbuffer_append_counted_string(sb, buf, 1, 1)) + return 1; + } else if (c == ' ' && space_is_plus) { + *buf = '+'; + + if(raptor_stringbuffer_append_counted_string(sb, buf, 1, 1)) + return 1; + } else { + *buf = '%'; + if(raptor_stringbuffer_append_counted_string(sb, buf, 1, 1)) + return 1; + + if(raptor_stringbuffer_append_hexadecimal(sb, (c & 0xf0) >> 4)) + return 1; + + if(raptor_stringbuffer_append_hexadecimal(sb, (c & 0x0f))) + return 1; + } + } + + return 0; +} + + +#endif + + + +#ifdef STANDALONE + +/* one more prototype */ +int main(int argc, char *argv[]); + + +int +main(int argc, char *argv[]) +{ + const char *program = raptor_basename(argv[0]); +#define TEST_ITEMS_COUNT 9 + const char *items[TEST_ITEMS_COUNT] = { "the", "quick" ,"brown", "fox", "jumps", "over", "the", "lazy", "dog" }; + const char *items_string = "thequickbrownfoxjumpsoverthelazydog"; + const size_t items_len = 35; + const char *test_integer_string = "abcd"; +#define TEST_INTEGERS_COUNT 7 + const int test_integers[TEST_INTEGERS_COUNT]={ 0, 1, -1, 11, 1234, 12345, -12345 }; + const char *test_integer_results[TEST_INTEGERS_COUNT]={ "abcd0", "abcd1", "abcd-1", "abcd11", "abcd1234", "abcd12345", "abcd-12345" }; + raptor_stringbuffer *sb; + unsigned char *str; + size_t len; + int i = 0; + raptor_stringbuffer *sb1, *sb2; +#define TEST_APPEND_COUNT 2 + const char *test_append_results[TEST_APPEND_COUNT]={ "thebrownjumpsthedog", "quickfoxoverlazy" }; + const char *test_append_results_total="thebrownjumpsthedogquickfoxoverlazy"; +#define COPY_STRING_BUFFER_SIZE 100 + unsigned char *copy_string; + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Creating string buffer\n", program); +#endif + + /* test appending */ + + sb = raptor_new_stringbuffer(); + if(!sb) { + fprintf(stderr, "%s: Failed to create string buffer\n", program); + exit(1); + } + + for(i = 0; i < TEST_ITEMS_COUNT; i++) { + int rc; + len = strlen(items[i]); + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Adding string buffer item '%s'\n", program, items[i]); +#endif + + rc = raptor_stringbuffer_append_counted_string(sb, (unsigned char*)items[i], len, 1); + if(rc) { + fprintf(stderr, "%s: Adding string buffer item %d '%s' failed, returning error %d\n", + program, i, items[i], rc); + exit(1); + } + } + + len = raptor_stringbuffer_length(sb); + if(len != items_len) { + fprintf(stderr, "%s: string buffer len is %d, expected %d\n", program, + (int)len, (int)items_len); + exit(1); + } + + str = raptor_stringbuffer_as_string(sb); + if(strcmp((const char*)str, items_string)) { + fprintf(stderr, "%s: string buffer contains '%s', expected '%s'\n", + program, str, items_string); + exit(1); + } + + raptor_free_stringbuffer(sb); + + + /* test prepending */ + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Creating string buffer\n", program); +#endif + + sb = raptor_new_stringbuffer(); + if(!sb) { + fprintf(stderr, "%s: Failed to create string buffer\n", program); + exit(1); + } + + for(i = TEST_ITEMS_COUNT-1; i>=0 ; i--) { + int rc; + len = strlen(items[i]); + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Prepending string buffer item '%s'\n", program, items[i]); +#endif + + rc = raptor_stringbuffer_prepend_counted_string(sb, (unsigned char*)items[i], len, 1); + if(rc) { + fprintf(stderr, "%s: Prepending string buffer item %d '%s' failed, returning error %d\n", + program, i, items[i], rc); + exit(1); + } + } + + len = raptor_stringbuffer_length(sb); + if(len != items_len) { + fprintf(stderr, "%s: string buffer len is %d, expected %d\n", program, + (int)len, (int)items_len); + exit(1); + } + + str = raptor_stringbuffer_as_string(sb); + if(strcmp((const char*)str, items_string)) { + fprintf(stderr, "%s: string buffer contains '%s', expected '%s'\n", + program, str, items_string); + exit(1); + } + + + /* test adding integers */ + + for(i = 0; i < TEST_INTEGERS_COUNT; i++) { + raptor_stringbuffer *isb = raptor_new_stringbuffer(); + if(!isb) { + fprintf(stderr, "%s: Failed to create string buffer\n", program); + exit(1); + } + + raptor_stringbuffer_append_string(isb, + (const unsigned char*)test_integer_string, 1); + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Adding decimal integer %d to buffer\n", program, test_integers[i]); +#endif + + raptor_stringbuffer_append_decimal(isb, test_integers[i]); + + str = raptor_stringbuffer_as_string(isb); + if(strcmp((const char*)str, test_integer_results[i])) { + fprintf(stderr, "%s: string buffer contains '%s', expected '%s'\n", + program, str, test_integer_results[i]); + exit(1); + } +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Freeing string buffer\n", program); +#endif + raptor_free_stringbuffer(isb); + } + + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Creating two stringbuffers to join\n", program); +#endif + + sb1 = raptor_new_stringbuffer(); + if(!sb1) { + fprintf(stderr, "%s: Failed to create string buffer\n", program); + exit(1); + } + sb2 = raptor_new_stringbuffer(); + if(!sb2) { + fprintf(stderr, "%s: Failed to create string buffer\n", program); + exit(1); + } + + for(i = 0; i < TEST_ITEMS_COUNT; i++) { + raptor_stringbuffer *sbx; + int rc; + len = strlen(items[i]); + + sbx = (i % 2) ? sb2 : sb1; + rc = raptor_stringbuffer_append_counted_string(sbx, (unsigned char*)items[i], len, 1); + if(rc) { + fprintf(stderr, "%s: Adding string buffer item %d '%s' failed, returning error %d\n", + program, i, items[i], rc); + exit(1); + } + } + + if(1) { + int rc; + + rc = raptor_stringbuffer_append_counted_string(sb1, (unsigned char*)"X", 0, 1); + if(rc) { + fprintf(stderr, "%s: Adding 0-length counted string failed, returning error %d\n", + program, rc); + exit(1); + } + rc = raptor_stringbuffer_append_string(sb1, NULL, 1); + if(rc) { + fprintf(stderr, "%s: Adding NULL string failed, returning error %d\n", + program, rc); + exit(1); + } + } + + str = raptor_stringbuffer_as_string(sb1); + if(strcmp((const char*)str, test_append_results[0])) { + fprintf(stderr, "%s: string buffer sb1 contains '%s', expected '%s'\n", + program, str, test_append_results[0]); + exit(1); + } + str = raptor_stringbuffer_as_string(sb2); + if(strcmp((const char*)str, test_append_results[1])) { + fprintf(stderr, "%s: string buffer sb2 contains '%s', expected '%s'\n", + program, str, test_append_results[1]); + exit(1); + } + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Appended two stringbuffers\n", program); +#endif + + if(raptor_stringbuffer_append_stringbuffer(sb1, sb2)) { + fprintf(stderr, "%s: Failed to append string buffer\n", program); + exit(1); + } + + str = raptor_stringbuffer_as_string(sb1); + if(strcmp((const char*)str, test_append_results_total)) { + fprintf(stderr, "%s: appended string buffer contains '%s', expected '%s'\n", + program, str, test_append_results_total); + exit(1); + } + + len = raptor_stringbuffer_length(sb2); + if(len) { + fprintf(stderr, "%s: appended string buffer is length %d, not empty'\n", + program, (int)len); + exit(1); + } + + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Copying string buffer to string\n", program); +#endif + + copy_string = (unsigned char*)malloc(COPY_STRING_BUFFER_SIZE); + if(raptor_stringbuffer_copy_to_string(sb1, copy_string, COPY_STRING_BUFFER_SIZE)) { + fprintf(stderr, "%s: copying string buffer to string failed\n", + program); + exit(1); + } + if(strcmp((const char*)copy_string, test_append_results_total)) { + fprintf(stderr, "%s: copied string buffer contains '%s', expected '%s'\n", + program, copy_string, test_append_results_total); + exit(1); + } + free(copy_string); + + +#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 + fprintf(stderr, "%s: Freeing string buffers\n", program); +#endif + raptor_free_stringbuffer(sb1); + raptor_free_stringbuffer(sb2); + raptor_free_stringbuffer(sb); + + /* keep gcc -Wall happy */ + return(0); +} + +#endif |