Overview
Comment: | Preliminary OFXMLElement implementation. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
f9c673f241858ecb4837f20a43c2a9f7 |
User & Date: | js on 2009-06-18 18:42:16 |
Other Links: | manifest | tags |
Context
2009-06-18
| ||
19:08 | Get rid of OFXMLFactory. check-in: 612bc150e5 user: js tags: trunk | |
18:42 | Preliminary OFXMLElement implementation. check-in: f9c673f241 user: js tags: trunk | |
18:26 | Add -[appendCStringWithoutUTF8Checking:]. check-in: 47e65e5a97 user: js tags: trunk | |
Changes
Modified src/Makefile from [a44f2314dd] to [8ef38350d8].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ${OFPLUGIN_M} \ OFSocket.m \ OFStream.m \ OFString.m \ OFTCPSocket.m \ OFThread.m \ OFURLEncoding.m \ OFXMLFactory.m \ INCLUDESTMP := ${SRCS:.c=.h} INCLUDES := ${INCLUDESTMP:.m=.h} \ OFMacros.h \ asprintf.h \ objfw.h | > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ${OFPLUGIN_M} \ OFSocket.m \ OFStream.m \ OFString.m \ OFTCPSocket.m \ OFThread.m \ OFURLEncoding.m \ OFXMLElement.m \ OFXMLFactory.m \ INCLUDESTMP := ${SRCS:.c=.h} INCLUDES := ${INCLUDESTMP:.m=.h} \ OFMacros.h \ asprintf.h \ objfw.h |
︙ | ︙ |
Modified src/OFDictionary.m from [3ec4eb0e31] to [ea26220ad7].
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include <string.h> #import "OFDictionary.h" #import "OFIterator.h" #import "OFExceptions.h" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <string.h> #import "OFDictionary.h" #import "OFIterator.h" #import "OFExceptions.h" /* References for static linking */ void _references_to_categories_of_OFDictionary() { _OFIterator_reference = 1; } @implementation OFDictionary + dictionary; |
︙ | ︙ |
Modified src/OFString.h from [c66ab2551c] to [bbf5506e5d].
︙ | ︙ | |||
150 151 152 153 154 155 156 | - removeTrailingWhitespaces; - removeLeadingAndTrailingWhitespaces; @end #import "OFConstString.h" #import "OFMutableString.h" #import "OFURLEncoding.h" | > | 150 151 152 153 154 155 156 157 | - removeTrailingWhitespaces; - removeLeadingAndTrailingWhitespaces; @end #import "OFConstString.h" #import "OFMutableString.h" #import "OFURLEncoding.h" #import "OFXMLElement.h" |
Modified src/OFString.m from [f0f301f9d4] to [1b2b877044].
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 | #else #define madvise(addr, len, advise) #endif #import "OFString.h" #import "OFAutoreleasePool.h" #import "OFURLEncoding.h" #import "OFExceptions.h" #import "OFMacros.h" #import "asprintf.h" | > | > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #else #define madvise(addr, len, advise) #endif #import "OFString.h" #import "OFAutoreleasePool.h" #import "OFURLEncoding.h" #import "OFXMLElement.h" #import "OFExceptions.h" #import "OFMacros.h" #import "asprintf.h" /* References for static linking */ void _references_to_categories_of_OFString() { _OFURLEncoding_reference = 1; _OFXMLElement_reference = 1; }; int of_string_check_utf8(const char *str, size_t len) { size_t i; int utf8 = 0; |
︙ | ︙ |
Added src/OFXMLElement.h version [d7c56955ee].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* * Copyright (c) 2008 - 2009 * Jonathan Schleifer <js@webkeks.org> * * 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. */ #import "OFObject.h" #import "OFString.h" #import "OFDictionary.h" #import "OFArray.h" extern int _OFXMLElement_reference; @interface OFXMLElement: OFObject { OFString *name; OFDictionary *attrs; OFString *stringval; OFArray *children; } + elementWithName: (OFString*)name; + elementWithName: (OFString*)name andStringValue: (OFString*)stringval; - initWithName: (OFString*)name; - initWithName: (OFString*)name andStringValue: (OFString*)stringval; - (OFString*)string; - addAttributeWithName: (OFString*)name andValue: (OFString*)value; - addChild: (OFXMLElement*)child; @end @interface OFString (OFXMLEscaping) - stringByXMLEscaping; @end |
Added src/OFXMLElement.m version [61f052da6e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | /* * Copyright (c) 2008 - 2009 * Jonathan Schleifer <js@webkeks.org> * * 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 <assert.h> #include <stdlib.h> #include <string.h> #import "OFXMLElement.h" #import "OFAutoreleasePool.h" #import "OFExceptions.h" int _OFXMLElement_reference; @implementation OFXMLElement + elementWithName: (OFString*)name_ { return [[[self alloc] initWithName: name_] autorelease]; } + elementWithName: (OFString*)name_ andStringValue: (OFString*)stringval_ { return [[[self alloc] initWithName: name_ andStringValue: stringval_] autorelease]; } - initWithName: (OFString*)name_ { self = [super init]; name = [name_ retain]; return self; } - initWithName: (OFString*)name_ andStringValue: (OFString*)stringval_ { self = [super init]; name = [name_ retain]; stringval = [stringval_ retain]; return self; } - (OFString*)string { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; char *str_c; size_t len, i, j; OFString *ret, *tmp; OFIterator *iter; len = [name length] + 4; str_c = [self allocMemoryWithSize: len]; /* Start of tag */ *str_c = '<'; memcpy(str_c + 1, [name cString], [name length]); i = [name length] + 1; /* Attributes */ iter = [attrs iterator]; for (;;) { OFString *key, *val; key = [iter nextObject]; val = [iter nextObject]; if (key == nil || val == nil) break; tmp = [val stringByXMLEscaping]; len += [key length] + [tmp length] + 4; @try { str_c = [self resizeMemory: str_c toSize: len]; } @catch (OFException *e) { [self freeMemory: str_c]; @throw e; } str_c[i++] = ' '; memcpy(str_c + i, [key cString], [key length]); i += [key length]; str_c[i++] = '='; str_c[i++] = '\''; memcpy(str_c + i, [tmp cString], [tmp length]); i += [tmp length]; str_c[i++] = '\''; [pool releaseObjects]; } /* Childen */ if (stringval != nil || children != nil) { if (stringval != nil) tmp = [stringval stringByXMLEscaping]; else if (children != nil) { OFXMLElement **data = [children data]; size_t count = [children count]; IMP append; tmp = [OFMutableString string]; append = [tmp methodFor: @selector( appendCStringWithoutUTF8Checking:)]; for (j = 0; j < count; j++) append(tmp, @selector( appendCStringWithoutUTF8Checking:), [[data[j] string] cString]); } len += [tmp length] + [name length] + 2; @try { str_c = [self resizeMemory: str_c toSize: len]; } @catch (OFException *e) { [self freeMemory: str_c]; @throw e; } str_c[i++] = '>'; memcpy(str_c + i, [tmp cString], [tmp length]); i += [tmp length]; str_c[i++] = '<'; str_c[i++] = '/'; memcpy(str_c + i, [name cString], [name length]); i += [name length]; } else str_c[i++] = '/'; str_c[i++] = '>'; str_c[i++] = '\0'; assert(i == len); [pool release]; @try { ret = [OFString stringWithCString: str_c]; } @finally { [self freeMemory: str_c]; } return ret; } - addAttributeWithName: (OFString*)name_ andValue: (OFString*)value_ { if (attrs == nil) attrs = [[OFMutableDictionary alloc] init]; [attrs setObject: value_ forKey: name_]; return self; } - addChild: (OFXMLElement*)child { if (stringval != nil) @throw [OFInvalidArgumentException newWithClass: isa andSelector: _cmd]; if (children == nil) children = [[OFMutableArray alloc] init]; [children addObject: child]; return self; } - (void)dealloc { [name release]; [attrs release]; [stringval release]; [children release]; [super dealloc]; } @end @implementation OFString (OFXMLEscaping) - stringByXMLEscaping { char *str_c, *append, *tmp; size_t len, append_len; size_t i, j; OFString *ret; j = 0; len = length + 1; /* * We can't use allocMemoryWithSize: here as it might be a @"" literal */ if ((str_c = malloc(len + 1)) == NULL) @throw [OFOutOfMemoryException newWithClass: isa andSize: len]; for (i = 0; i < length; i++) { switch (string[i]) { case '<': append = "<"; append_len = 4; break; case '>': append = ">"; append_len = 4; break; case '"': append = """; append_len = 6; break; case '\'': append = "'"; append_len = 6; break; case '&': append = "&"; append_len = 5; break; default: append = NULL; append_len = 0; } if (append != NULL) { if ((tmp = realloc(str_c, len + append_len)) == NULL) { free(str_c); @throw [OFOutOfMemoryException newWithClass: isa andSize: len + append_len]; } str_c = tmp; len += append_len - 1; memcpy(str_c + j, append, append_len); j += append_len; } else str_c[j++] = string[i]; } str_c[j++] = '\0'; assert(j == len); @try { ret = [OFString stringWithCString: str_c]; } @finally { free(str_c); } return ret; } @end |
Modified tests/Makefile from [d93b2a7df0] to [819d55b057].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | include ../extra.mk SUBDIRS = OFObject \ OFAutoreleasePool \ OFDataArray \ OFArray \ OFDictionary \ OFHashes \ ${OFPLUGIN} \ OFString \ OFTCPSocket \ OFThread \ OFList \ OFXMLFactory \ ${OBJC_SYNC} include ../buildsys.mk | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | include ../extra.mk SUBDIRS = OFObject \ OFAutoreleasePool \ OFDataArray \ OFArray \ OFDictionary \ OFHashes \ ${OFPLUGIN} \ OFString \ OFTCPSocket \ OFThread \ OFList \ OFXMLElement \ OFXMLFactory \ ${OBJC_SYNC} include ../buildsys.mk |
Modified tests/OFString/OFString.m from [8785c62127] to [fa55c2ad9d].
︙ | ︙ | |||
21 22 23 24 25 26 27 | #ifndef _WIN32 #define ZD "%zd" #else #define ZD "%u" #endif | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef _WIN32 #define ZD "%zd" #else #define ZD "%u" #endif #define NUM_TESTS 34 #define SUCCESS \ printf("\r\033[1;%dmTests successful: " ZD "/%d\033[0m", \ (i == NUM_TESTS - 1 ? 32 : 33), i + 1, NUM_TESTS); \ fflush(stdout); #define FAIL \ printf("\r\033[K\033[1;31mTest " ZD "/%d failed!\033[m\n", \ i + 1, NUM_TESTS); \ |
︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | /* Format tests */ s1 = [OFMutableString stringWithFormat: @"%s: %d", "test", 123]; CHECK(!strcmp([s1 cString], "test: 123")) [s1 appendWithFormat: @"%02X", 15]; CHECK(!strcmp([s1 cString], "test: 1230F")) a = [@"fooXXbarXXXXbazXXXX" splitWithDelimiter: @"XX"]; CHECK([[a objectAtIndex: j++] isEqual: @"foo"]) CHECK([[a objectAtIndex: j++] isEqual: @"bar"]) CHECK([[a objectAtIndex: j++] isEqual: @""]) CHECK([[a objectAtIndex: j++] isEqual: @"baz"]) CHECK([[a objectAtIndex: j++] isEqual: @""]) CHECK([[a objectAtIndex: j++] isEqual: @""]) CHECK([[@"foo\"ba'_$" stringByURLEncoding] isEqual: @"foo%22ba%27_%24"]) CHECK([[@"foo%20bar%22%24" stringByURLDecoding] isEqual: @"foo bar\"$"]) CHECK_EXCEPT([@"foo%bar" stringByURLDecoding], OFInvalidEncodingException) CHECK_EXCEPT([@"foo%FFbar" stringByURLDecoding], OFInvalidEncodingException) s1 = [@"asd fo asd fofo asd" mutableCopy]; [s1 replaceOccurrencesOfString: @"fo" withString: @"foo"]; CHECK([s1 isEqual: @"asd foo asd foofoo asd"]) s1 = [@"XX" mutableCopy]; [s1 replaceOccurrencesOfString: @"X" withString: @"XX"]; CHECK([s1 isEqual: @"XXXX"]) s1 = [@" \t\t \tasd \t \t\t" mutableCopy]; s2 = [s1 mutableCopy]; s3 = [s1 mutableCopy]; CHECK([[s1 removeLeadingWhitespaces] isEqual: @"asd \t \t\t"]) CHECK([[s2 removeTrailingWhitespaces] isEqual: @" \t\t \tasd"]) CHECK([[s3 removeLeadingAndTrailingWhitespaces] isEqual: @"asd"]) s1 = [@" \t\t \t\t \t \t" mutableCopy]; s2 = [s1 mutableCopy]; s3 = [s1 mutableCopy]; CHECK([[s1 removeLeadingWhitespaces] isEqual: @""]) CHECK([[s2 removeTrailingWhitespaces] isEqual: @""]) CHECK([[s3 removeLeadingAndTrailingWhitespaces] isEqual: @""]) puts(""); return 0; } | > > > > > > > > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | /* Format tests */ s1 = [OFMutableString stringWithFormat: @"%s: %d", "test", 123]; CHECK(!strcmp([s1 cString], "test: 123")) [s1 appendWithFormat: @"%02X", 15]; CHECK(!strcmp([s1 cString], "test: 1230F")) /* Split tests */ a = [@"fooXXbarXXXXbazXXXX" splitWithDelimiter: @"XX"]; CHECK([[a objectAtIndex: j++] isEqual: @"foo"]) CHECK([[a objectAtIndex: j++] isEqual: @"bar"]) CHECK([[a objectAtIndex: j++] isEqual: @""]) CHECK([[a objectAtIndex: j++] isEqual: @"baz"]) CHECK([[a objectAtIndex: j++] isEqual: @""]) CHECK([[a objectAtIndex: j++] isEqual: @""]) /* URL encoding tests */ CHECK([[@"foo\"ba'_$" stringByURLEncoding] isEqual: @"foo%22ba%27_%24"]) CHECK([[@"foo%20bar%22%24" stringByURLDecoding] isEqual: @"foo bar\"$"]) CHECK_EXCEPT([@"foo%bar" stringByURLDecoding], OFInvalidEncodingException) CHECK_EXCEPT([@"foo%FFbar" stringByURLDecoding], OFInvalidEncodingException) /* Replace tests */ s1 = [@"asd fo asd fofo asd" mutableCopy]; [s1 replaceOccurrencesOfString: @"fo" withString: @"foo"]; CHECK([s1 isEqual: @"asd foo asd foofoo asd"]) s1 = [@"XX" mutableCopy]; [s1 replaceOccurrencesOfString: @"X" withString: @"XX"]; CHECK([s1 isEqual: @"XXXX"]) /* Whitespace removing tests */ s1 = [@" \t\t \tasd \t \t\t" mutableCopy]; s2 = [s1 mutableCopy]; s3 = [s1 mutableCopy]; CHECK([[s1 removeLeadingWhitespaces] isEqual: @"asd \t \t\t"]) CHECK([[s2 removeTrailingWhitespaces] isEqual: @" \t\t \tasd"]) CHECK([[s3 removeLeadingAndTrailingWhitespaces] isEqual: @"asd"]) s1 = [@" \t\t \t\t \t \t" mutableCopy]; s2 = [s1 mutableCopy]; s3 = [s1 mutableCopy]; CHECK([[s1 removeLeadingWhitespaces] isEqual: @""]) CHECK([[s2 removeTrailingWhitespaces] isEqual: @""]) CHECK([[s3 removeLeadingAndTrailingWhitespaces] isEqual: @""]) /* XML escaping tests */ s1 = [@"<hello> &world'\"!&" stringByXMLEscaping]; CHECK([s1 isEqual: @"<hello> &world'"!&"]) puts(""); return 0; } |
Added tests/OFXMLElement/Makefile version [280a3ac556].
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | PROG_NOINST = ofxmlelement${PROG_SUFFIX} SRCS = OFXMLElement.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 |
Added tests/OFXMLElement/OFXMLElement.m version [0ba42ffac8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | /* * Copyright (c) 2008 - 2009 * Jonathan Schleifer <js@webkeks.org> * * 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 <stdio.h> #import "OFXMLElement.h" #ifndef _WIN32 #define ZD "%zd" #else #define ZD "%u" #endif #define NUM_TESTS 5 #define SUCCESS \ printf("\r\033[1;%dmTests successful: " ZD "/%d\033[0m", \ (i == NUM_TESTS - 1 ? 32 : 33), i + 1, NUM_TESTS); \ fflush(stdout); #define FAIL \ printf("\r\033[K\033[1;31mTest " ZD "/%d failed!\033[m\n", \ i + 1, NUM_TESTS); \ return 1; #define CHECK(cond) \ if (cond) { \ SUCCESS \ } else { \ FAIL \ } \ i++; #define CHECK_EXCEPT(code, exception) \ @try { \ code; \ FAIL \ } @catch (exception *e) { \ SUCCESS \ } \ i++; int main() { size_t i = 0; OFXMLElement *elem; elem = [OFXMLElement elementWithName: @"foo"]; CHECK([[elem string] isEqual: @"<foo/>"]); [elem addAttributeWithName: @"foo" andValue: @"b&ar"]; CHECK([[elem string] isEqual: @"<foo foo='b&ar'/>"]) [elem addChild: [OFXMLElement elementWithName: @"bar"]]; CHECK([[elem string] isEqual: @"<foo foo='b&ar'><bar/></foo>"]) elem = [OFXMLElement elementWithName: @"foo" andStringValue: @"b&ar"]; CHECK([[elem string] isEqual: @"<foo>b&ar</foo>"]) [elem addAttributeWithName: @"foo" andValue: @"b&ar"]; CHECK([[elem string] isEqual: @"<foo foo='b&ar'>b&ar</foo>"]) puts(""); return 0; } |