Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -24,12 +24,11 @@ OFStream.m \ OFString.m \ OFTCPSocket.m \ OFThread.m \ OFURLEncoding.m \ - OFXMLElement.m \ - OFXMLFactory.m \ + OFXMLElement.m INCLUDESTMP := ${SRCS:.c=.h} INCLUDES := ${INCLUDESTMP:.m=.h} \ OFMacros.h \ asprintf.h \ DELETED src/OFXMLFactory.h Index: src/OFXMLFactory.h ================================================================== --- src/OFXMLFactory.h +++ src/OFXMLFactory.h @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2008 - 2009 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of libobjfw. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE included in - * the packaging of this file. - */ - -#include - -#import "OFObject.h" - -/** - * The OFXMLFactory class provides an easy way to create XML stanzas. - */ -@interface OFXMLFactory: OFObject {} -/** - * XML-escapes a C string. - * - * \param s The C string to escape - * \return The escaped C string. - * You need to free it manually! - */ -+ (char*)escapeCString: (const char*)s; - -/** - * Creates an XML stanza. - * - * \param name The name of the tag as a C string - * \param ... Field / value pairs for the tag in the form "field", "value" as - * C strings. - * Last element must be NULL. - * Example: "field1", "value1", "field2", "value2", NULL - * \return The created XML stanza as a C string. - * You need to free it manually! - */ -+ (char*)createStanza: (const char*)name, ...; - -/** - * Creates an XML stanza. - * - * \param name The name of the tag as a C string - * \param data Data that should be inside the tag as a C string. - * It will NOT be escaped, so you can also include other stanzas. - * \param ... Field / value pairs for the tag in the form "field", "value" as - * C strings. - * Last element must be NULL. - * Example: "field1", "value1", "field2", "value2", NULL - * \return The created XML stanza as a C string. - * You need to free it manually! - */ -+ (char*)createStanza: (const char*)name - withData: (const char*)data, ...; - -/** - * Creates an XML stanza. - * - * \param name The name of the tag as a C string - * \param close A boolean whether the tag should be closed - * \param data Data that should be inside the tag as a C string. - * It will NOT be escaped, so you can also include other stanzas. - * \param ... Field / value pairs for the tag in the form "field", "value" as - * C strings. - * Last element must be NULL. - * Example: "field1", "value1", "field2", "value2", NULL - * \return The created XML stanza as a C string. - * You need to free it manually! - */ -+ (char*)createStanza: (const char*)name - withCloseTag: (BOOL)close - andData: (const char*)data, ...; - -/** - * Creates an XML stanza. - * - * \param name The name of the tag as a C string - * \param close A boolean whether the tag should be closed - * \param attrs Field / value pairs for the tag in the form "field", "value" as - * C strings inside a va_list. - * Last element must be NULL. - * Example: "field1", "value1", "field2", "value2", NULL in a va_list - * \param data Data that should be inside the tag as a C string. - * It will NOT be escaped, so you can also include other stanzas. - * \return The created XML stanza as a C string. - * You need to free it manually! - */ -+ (char*)createStanza: (const char*)name - withCloseTag: (BOOL)close - andAttributes: (va_list)attrs - andData: (const char*)data; - -/** - * Concats an array of C strings into one C string and frees the array of C - * strings. - * - * \param strs An array of C strings - * \return The concatenated C strings. - * You need to free it manually! - */ -+ (char*)concatAndFreeCStrings: (char**)strs; -@end DELETED src/OFXMLFactory.m Index: src/OFXMLFactory.m ================================================================== --- src/OFXMLFactory.m +++ src/OFXMLFactory.m @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2008 - 2009 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of libobjfw. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE included in - * the packaging of this file. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#import "OFXMLFactory.h" -#import "OFExceptions.h" -#import "OFMacros.h" - -/* - * We don't use OFString in this file for performance reasons! - * - * We already have a clue about how big the resulting string will get, so we - * can prealloc and only resize when really necessary - OFString would always - * resize when we append, which would be slow here. - */ - -static inline void -resize(char **str, size_t *len, size_t add, Class class) -{ - char *str2; - size_t len2; - - if (add > SIZE_MAX - *len) - @throw [OFOutOfRangeException newWithClass: class]; - len2 = *len + add; - - if ((str2 = realloc(*str, len2)) == NULL) { - if (*str) - free(*str); - *str = NULL; - @throw [OFOutOfMemoryException newWithClass: class - andSize: len2]; - } - - *str = str2; - *len = len2; -} - -static inline void -append(char **str, size_t *len, size_t *pos, const char *add, Class class) -{ - size_t add_len; - - add_len = strlen(add); - - resize(str, len, add_len, class); - - memcpy(*str + *pos, add, add_len); - *pos += add_len; -} - -@implementation OFXMLFactory -+ (char*)escapeCString: (const char*)s -{ - char *ret; - size_t i, len; - - len = strlen(s); - if (SIZE_MAX - len < 1) - @throw [OFOutOfRangeException newWithClass: self]; - - len++; - if ((ret = malloc(len)) == NULL) - @throw [OFOutOfMemoryException newWithClass: self - andSize: len]; - - @try { - for (i = 0; *s; s++) { - switch (*s) { - case '<': - append(&ret, &len, &i, "<", self); - break; - case '>': - append(&ret, &len, &i, ">", self); - break; - case '"': - append(&ret, &len, &i, """, self); - break; - case '\'': - append(&ret, &len, &i, "'", self); - break; - case '&': - append(&ret, &len, &i, "&", self); - break; - default: - ret[i++] = *s; - break; - } - } - } @catch (OFException *e) { - free(ret); - @throw e; - } - - ret[i] = 0; - return ret; -} - -+ (char*)createStanza: (const char*)name, ... -{ - char *ret; - va_list attrs; - - va_start(attrs, name); - ret = [self createStanza: name - withCloseTag: YES - andAttributes: attrs - andData: NULL]; - va_end(attrs); - - return ret; -} - -+ (char*)createStanza: (const char*)name - withData: (const char*)data, ... -{ - char *ret; - va_list attrs; - - va_start(attrs, data); - ret = [self createStanza: name - withCloseTag: YES - andAttributes: attrs - andData: data]; - va_end(attrs); - - return ret; -} - -+ (char*)createStanza: (const char*)name - withCloseTag: (BOOL)close - andData: (const char*)data, ... -{ - char *ret; - va_list attrs; - - va_start(attrs, data); - ret = [self createStanza: name - withCloseTag: close - andAttributes: attrs - andData: data]; - va_end(attrs); - - return ret; -} - -+ (char*)createStanza: (const char*)name - withCloseTag: (BOOL)close - andAttributes: (va_list)attrs - andData: (const char*)data -{ - char *arg, *val, *xml, *esc_val = NULL; - size_t i, len; - - /* Start of tag */ - len = strlen(name); - if (SIZE_MAX - len < 3) - @throw [OFOutOfRangeException newWithClass: self]; - len += 3; - - if ((xml = malloc(len)) == NULL) - @throw [OFOutOfMemoryException newWithClass: self - andSize: len]; - - i = 0; - xml[i++] = '<'; - memcpy(xml + i, name, strlen(name)); - i += strlen(name); - - @try { - while ((arg = va_arg(attrs, char*)) != NULL && - (val = va_arg(attrs, char*)) != NULL) { - esc_val = NULL; /* Needed for our @catch */ - esc_val = [self escapeCString: val]; - - resize(&xml, &len, 1 + strlen(arg) + 2 + - strlen(esc_val) + 1, self); - - xml[i++] = ' '; - memcpy(xml + i, arg, strlen(arg)); - i += strlen(arg); - xml[i++] = '='; - xml[i++] = '\''; - memcpy(xml + i, esc_val, strlen(esc_val)); - i += strlen(esc_val); - xml[i++] = '\''; - - free(esc_val); - } - - /* End of tag */ - if (close) { - if (data == NULL) { - resize(&xml, &len, 2 - 1, self); - - xml[i++] = '/'; - xml[i++] = '>'; - } else { - resize(&xml, &len, 1 + strlen(data) + 2 + - strlen(name) + 1 - 1, self); - - xml[i++] = '>'; - memcpy(xml + i, data, strlen(data)); - i += strlen(data); - xml[i++] = '<'; - xml[i++] = '/'; - memcpy(xml + i, name, strlen(name)); - i += strlen(name); - xml[i++] = '>'; - } - } else - xml[i++] = '>'; - } @catch (OFException *e) { - if (esc_val != NULL) - free(esc_val); - free(xml); - @throw e; - } - - xml[i] = 0; - return xml; -} - -+ (char*)concatAndFreeCStrings: (char**)strs -{ - char *ret; - size_t i, len, pos; - - if (strs[0] == NULL) - return NULL; - - len = strlen(*strs); - if (SIZE_MAX - len < 1) - @throw [OFOutOfRangeException newWithClass: self]; - len++; - - if ((ret = malloc(len)) == NULL) - @throw [OFOutOfMemoryException newWithClass: self - andSize: len]; - - memcpy(ret, strs[0], len - 1); - pos = len - 1; - - @try { - for (i = 1; strs[i] != NULL; i++) - append(&ret, &len, &pos, strs[i], self); - - for (i = 0; strs[i] != NULL; i++) - free(strs[i]); - } @catch (OFException *e) { - free(ret); - @throw e; - } - - ret[pos] = 0; - return ret; -} -@end Index: src/objfw.h ================================================================== --- src/objfw.h +++ src/objfw.h @@ -32,13 +32,13 @@ #import "OFSocket.h" #import "OFTCPSocket.h" #import "OFHashes.h" #import "OFThread.h" -#import "OFXMLFactory.h" +#import "OFXMLElement.h" #ifdef OF_PLUGINS #import "OFPlugin.h" #endif #import "OFMacros.h" #import "asprintf.h" Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -10,9 +10,8 @@ OFString \ OFTCPSocket \ OFThread \ OFList \ OFXMLElement \ - OFXMLFactory \ ${OBJC_SYNC} include ../buildsys.mk DELETED tests/OFXMLFactory/Makefile Index: tests/OFXMLFactory/Makefile ================================================================== --- tests/OFXMLFactory/Makefile +++ tests/OFXMLFactory/Makefile @@ -1,25 +0,0 @@ -PROG_NOINST = ofxmlfactory${PROG_SUFFIX} -SRCS = OFXMLFactory.m - -include ../../buildsys.mk -include ../../extra.mk - -CPPFLAGS += -I../../src -I../.. -LIBS := -L../../src -lobjfw ${LIBS} - -.PHONY: run - -all: run -run: ${PROG_NOINST} - rm -f libobjfw.so.0 libobjfw.so.0.1 libobjfw.dll libobjfw.dylib - ln -s ../../src/libobjfw.so libobjfw.so.0 - ln -s ../../src/libobjfw.so libobjfw.so.0.1 - if test -f ../../src/libobjfw.dll; then \ - ln ../../src/libobjfw.dll libobjfw.dll; \ - fi - ln -s ../../src/libobjfw.dylib libobjfw.dylib - LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ - DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ - ${TEST_LAUNCHER} ./${PROG_NOINST}; EXIT=$$?; \ - rm -f libobjfw.so.0 libobjfw.so.0.1 libobjfw.dll libobjfw.dylib; \ - exit $$EXIT DELETED tests/OFXMLFactory/OFXMLFactory.m Index: tests/OFXMLFactory/OFXMLFactory.m ================================================================== --- tests/OFXMLFactory/OFXMLFactory.m +++ tests/OFXMLFactory/OFXMLFactory.m @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2008 - 2009 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of libobjfw. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE included in - * the packaging of this file. - */ - -#include "config.h" - -#include -#include -#include - -#import "OFXMLFactory.h" - -#define NUM_TESTS 10 - -#ifndef _WIN32 -#define ZD "zd" -#else -#define ZD "u" -#endif - -static size_t i; - -inline void -check_result(char *result, const char *should) -{ - i++; - - if (!strcmp(result, should)) { - printf("\r\033[1;%dmTests successful: %2" ZD "/%d\033[0m", - (i == NUM_TESTS ? 32 : 33), i, NUM_TESTS); - fflush(stdout); - } else { - printf("\r\033[K\033[1;31mTest %" ZD "/%d failed!\033[0m\n", - i, NUM_TESTS); - printf("%s is NOT expected result!\n", result); - printf("Should have been: %s\n", result); - exit(1); - } - - free(result); -} - -inline void -test_concat() -{ - const char *c1 = "", *c2 = "bar", *c3 = ""; - char *s1, *s2, *s3; - char *strs[4]; - - if ((s1 = malloc(strlen(c1) + 1)) == NULL || - (s2 = malloc(strlen(c2) + 1)) == NULL || - (s3 = malloc(strlen(c3) + 1)) == NULL) - exit(1); - - strncpy(s1, c1, strlen(c1) + 1); - strncpy(s2, c2, strlen(c2) + 1); - strncpy(s3, c3, strlen(c3) + 1); - - strs[0] = s1; - strs[1] = s2; - strs[2] = s3; - strs[3] = NULL; - - check_result([OFXMLFactory concatAndFreeCStrings: strs], - "bar"); -} - -inline void -test_create_stanza() -{ - check_result([OFXMLFactory createStanza: "foo" - withCloseTag: NO - andData: NULL, - NULL], - ""); - - check_result([OFXMLFactory createStanza: "foo" - withCloseTag: NO - andData: NULL, - "bar", "baz", - "blub", "asd", - NULL], - ""); - check_result([OFXMLFactory createStanza: "foo", NULL], ""); - check_result([OFXMLFactory createStanza: "foo" - withData: "bar", - NULL], - "bar"); - check_result([OFXMLFactory createStanza: "foo", - "bar", "b&az", - NULL], - ""); - check_result([OFXMLFactory createStanza: "foo" - withData: "bar", - "bar", "b'az", - NULL], - "bar"); - check_result([OFXMLFactory createStanza: "foo", - "bar", "b&az", - "x", "asd\"", - NULL], - ""); - check_result([OFXMLFactory createStanza: "foo" - withData: "bar", - "bar", "b'az", - "x", "y", - "a", "b", - NULL], - "bar"); -} - -inline void -test_escape() -{ - check_result([OFXMLFactory escapeCString: " &welt'\"!&"], - "<hallo> &welt'"!&"); -} - -int main() -{ - i = 0; - test_escape(); - test_create_stanza(); - test_concat(); - puts(""); - - return 0; -}