DELETED SERIALIZATION
Index: SERIALIZATION
==================================================================
--- SERIALIZATION
+++ /dev/null
@@ -1,182 +0,0 @@
-1.) Basic Concept
-
-This document describes the serialization used by ObjFW. It is designed to be
-easy parsable and usable in other programming languages while still supporting
-ObjFW-specific features, which are all optional.
-
-Every object can have a set of parameters which are optional and can be ignored
-if they don't exist in the language for which parsing is done. These parameters
-are written in the form (parameter1,parameter2) and precede the object.
-Parameters not known by the implementation should be ignored - they are
-completely optional except for the extension type.
-
-All spaces (except those in strings, of course) are optional and only to improve
-readability - they are by no means required, but they are still recommended.
-
-ObjFW serialization supports 4 basic types: Strings, arrays and dictionaries.
-It is limited to those 4 types because those are available in all languages.
-Lists are a special case of arrays in ObjFW serialization. For all objects
-that can not be serialized with those 4 basic types, there is the extension
-type [], which can be used for any object but is not portable between languages.
-This type is described in 6.).
-
-
-2.) Strings
-
-Strings are very similar to how strings are done in C. They start with a " and
-end with a ". The escape sequences \", \\, \n, \r and \t exist, like in C
-strings. It is required to use \", \\, \n and \r. The reason for this is that
-using an actual newline would modify the string when indention is done. However,
-using \t is recommended.
-Strings can be split just like in C. For example "Hello " "World" is equivalent
-to "Hello World". Because this is possible, it is recommended to end the string
-after \n and continue it in a new line to increase readability.
-
-Strings are required to be UTF-8 encoded.
-
-The only accepted parameter for strings is mutable. If the language for which
-parsing is done does not know the concept of mutable and immutable objects, this
-parameter should be ignored.
-
-Examples for strings:
-
- "This is a \"string!\""
-
- "This is a string containing a\n"
- "new line!"
-
- "This is\ta string\tcontaining tabs!"
-
- (mutable)"This string is mutable!"
-
-
-3.) Arrays
-
-Arrays start with a [ and end with an ]. The elements are separated by a comma.
-Whitespaces are allowed between objects and after the inital [ and before the
-final ].
-
-It allows the mutable parameter, which should be handled the same way like it
-should be for strings.
-
-It also has the list parameter. Specifying this parameter creates a
-double-linked list instead of an array.
-
-It also allows specifying a number as a parameter. This number is considered
-the expected size of the array. It is by no means required and it should by no
-means be assumed to be reliable. If the number is not equal to the actual size,
-the parser should error out. The parser should also make sure to ignore the
-number if it is too big to prevent a possible DoS.
-
-Examples for arrays:
-
- ["This", "is", "an", "array", "with", "7", "strings"]
-
- (mutable)["This array", "is mutable"]
-
- (3)["This array specifies", "the number of elements", "for performance"]
-
- (mutable,2)["Parameters can be", "combined"]
-
-
-4.) Dictionaries
-
-Dictionary start with a { and end with a }. The elements are written in the form
-key = value and each entry ends with an ;.
-
-It allows the mutable parameter, which should be handled the same way like it
-should be for strings.
-
-It also allows specifying a number as a parameter, which should be handled
-exactly like for arrays.
-
-Examples for dictionaries:
-
- {"This is a key" = "This is a value"}
-
- (mutable){"mutable" = (BOOL)1}
-
- (2){
- "key1" = "value1",
- "key2" = "value2"
- }
-
- {
- ["Mapping", "an", "array"] = "To a string";
- { "mapping" = "a dictionary" } = ["To", "an", "array"];
- }
-
-
-5.) Numbers
-
-Numbers are written by just writing a number. The type of a number may be
-specified by a parameter. If it is not specified, the implementation should
-choose are type which fits the number. If the specified type is not big enough
-for the number, the implementation should use another type that fits.
-
-Known parameters are:
- BOOL
- char (signed!)
- short (signed!)
- int (signed!)
- long (signed!)
- int8_t
- int16_t
- int32_t
- int64_t
- unsigned char,
- unsigned short,
- unsigned int,
- unsigned long
- uint8_t
- uint16_t
- uint32_t
- uint64_t
- size_t
- ssize_t
- intmax_t
- uintmax_t
- intptr_t
- uintptr_t
- float
- double
-
-Examples for numbers:
-
- 1
- 2.6
- (BOOL)0
- (intmax_t)1234567
- (double)2.5
-
-
-6.) Extension Type
-
-The extension type allows adding new objects to ObjFW serialization. The
-extension type has a parameter class= which specifies the class which should
-handle deserialization and a version= parameter which specifies the version of
-the class serialization as a single integer. The extension type starts with a [
-and ends with a ]. Inside those brackets can be arbitray basic types, which
-should be passed unmodified to the class for deserialization.
-If an implementation can't deserialize an extension type, it is required to
-error out. Other languages are allowed to parse extension types of classes which
-are in ObjFW, like OFXMLElement, but are by no means required to do so. Other
-languages may also add their own extension types, but are required to add the
-foreign= parameter and set it to their name, so other implementations don't try
-to deserialize it, but error out instead. Other implementations are allowed to
-serialize to ObjFW objects if they know them. For example, it might be desirable
-to also create OFXMLElements from other languages.
-
-Examples for using the extension type:
-
- (class=OFXMLElement)<"">
-
- (class=OFURL)<
- "https://webkeks.org/objfw/"
- >
-
- (class=Foo,foreign=Foolang)<
- {
- "property1" = "value1"
- }
- >
Index: src/OFArray.m
==================================================================
--- src/OFArray.m
+++ src/OFArray.m
@@ -19,10 +19,11 @@
#include
#import "OFArray.h"
#import "OFDataArray.h"
#import "OFString.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#import "OFEnumerationMutationException.h"
#import "OFOutOfRangeException.h"
@@ -430,53 +431,32 @@
*/
ret->isa = [OFString class];
return ret;
}
-- (OFString*)stringBySerializing
+- (OFXMLElement*)XMLElementBySerializing
{
OFAutoreleasePool *pool;
- OFMutableString *ret;
- OFObject **cArray;
- size_t i, count;
-
- if ([array count] == 0) {
- if ([self isKindOfClass: [OFMutableArray class]])
- return @"(mutable,0)[]";
- else
- return @"(0)[]";
- }
-
- cArray = [array cArray];
- count = [array count];
- if ([self isKindOfClass: [OFMutableArray class]])
- ret = [OFMutableString stringWithFormat: @"(mutable,%zd)[\n",
- count];
- else
- ret = [OFMutableString stringWithFormat: @"(%zd)[\n", count];
+ OFXMLElement *element;
+ id *cArray = [array cArray];
+ size_t i, count = [array count];
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
pool = [[OFAutoreleasePool alloc] init];
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
- for (i = 0; i < count - 1; i++) {
- [ret appendString: [cArray[i] stringBySerializing]];
- [ret appendString: @",\n"];
-
+ for (i = 0; i < count; i++) {
+ [element addChild: [cArray[i] XMLElementBySerializing]];
[pool releaseObjects];
}
- [ret appendString: [cArray[i] stringBySerializing]];
- [ret replaceOccurrencesOfString: @"\n"
- withString: @"\n\t"];
- [ret appendString: @"\n]"];
[pool release];
- /*
- * Class swizzle the string to be immutable. We declared the return type
- * to be OFString*, so it can't be modified anyway. But not swizzling it
- * would create a real copy each time -[copy] is called.
- */
- ret->isa = [OFString class];
- return ret;
+ return element;
}
- (void)makeObjectsPerformSelector: (SEL)selector
{
id *cArray = [array cArray];
Index: src/OFDate.m
==================================================================
--- src/OFDate.m
+++ src/OFDate.m
@@ -23,11 +23,11 @@
#include
#import "OFDate.h"
#import "OFString.h"
#import "OFDictionary.h"
-#import "OFNumber.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#ifdef OF_THREADS
# import "OFThread.h"
#endif
@@ -289,27 +289,36 @@
- (OFString*)description
{
return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"];
}
-- (OFString*)stringBySerializing
-{
- OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
- OFDictionary *dictionary = [OFDictionary dictionaryWithKeysAndObjects:
- @"seconds", [OFNumber numberWithInt64: seconds],
- @"microseconds", [OFNumber numberWithUInt32: microseconds], nil];
- OFString *ret = [[OFString alloc]
- initWithFormat: @"(class=OFDate,version=0)<%@>",
- [dictionary stringBySerializing]];
-
- @try {
- [pool release];
- } @finally {
- [ret autorelease];
- }
-
- return ret;
+- (OFXMLElement*)XMLElementBySerializing
+{
+ OFAutoreleasePool *pool;
+ OFXMLElement *element;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
+ pool = [[OFAutoreleasePool alloc] init];
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
+
+ [element addChild:
+ [OFXMLElement elementWithName: @"seconds"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: [OFString stringWithFormat:
+ @"%" PRId64, seconds]]];
+ [element addChild:
+ [OFXMLElement elementWithName: @"microseconds"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: [OFString stringWithFormat:
+ @"%" PRIu32, microseconds]]];
+
+ [pool release];
+
+ return element;
}
- (uint32_t)microsecond
{
return microseconds;
Index: src/OFDictionary.m
==================================================================
--- src/OFDictionary.m
+++ src/OFDictionary.m
@@ -20,10 +20,11 @@
#import "OFDictionary.h"
#import "OFEnumerator.h"
#import "OFArray.h"
#import "OFString.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"
@@ -755,61 +756,55 @@
*/
ret->isa = [OFString class];
return ret;
}
-- (OFString*)stringBySerializing
+- (OFXMLElement*)XMLElementBySerializing
{
- OFMutableString *ret;
OFAutoreleasePool *pool, *pool2;
+ OFXMLElement *element;
OFEnumerator *keyEnumerator, *objectEnumerator;
- id key, object;
- size_t i;
-
- if (count == 0) {
- if ([self isKindOfClass: [OFMutableDictionary class]])
- return @"(mutable,0){}";
- else
- return @"(0){}";
- }
-
- if ([self isKindOfClass: [OFMutableDictionary class]])
- ret = [OFMutableString stringWithFormat: @"(mutable,%zd){\n",
- count];
- else
- ret = [OFMutableString stringWithFormat: @"(%zd){\n", count];
+ id key, object;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
pool = [[OFAutoreleasePool alloc] init];
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
+
keyEnumerator = [self keyEnumerator];
objectEnumerator = [self objectEnumerator];
- i = 0;
pool2 = [[OFAutoreleasePool alloc] init];
-
while ((key = [keyEnumerator nextObject]) != nil &&
- (object = [objectEnumerator nextObject]) != nil) {
- [ret appendString: [key stringBySerializing]];
- [ret appendString: @" = "];
- [ret appendString: [object stringBySerializing]];
+ (object = [objectEnumerator nextObject]) != nil) {
+ OFXMLElement *pair, *keyElement, *valueElement;
+
+ pair = [OFXMLElement elementWithName: @"pair"
+ namespace: OF_SERIALIZATION_NS];
+
+ keyElement = [OFXMLElement
+ elementWithName: @"key"
+ namespace: OF_SERIALIZATION_NS];
+ [keyElement addChild: [key XMLElementBySerializing]];
+ [pair addChild: keyElement];
+
+ valueElement = [OFXMLElement
+ elementWithName: @"value"
+ namespace: OF_SERIALIZATION_NS];
+ [valueElement addChild: [object XMLElementBySerializing]];
+ [pair addChild: valueElement];
- if (++i < count)
- [ret appendString: @",\n"];
+ [element addChild: pair];
[pool2 releaseObjects];
}
- [ret replaceOccurrencesOfString: @"\n"
- withString: @"\n\t"];
- [ret appendString: @"\n}"];
[pool release];
- /*
- * Class swizzle the string to be immutable. We declared the return type
- * to be OFString*, so it can't be modified anyway. But not swizzling it
- * would create a real copy each time -[copy] is called.
- */
- ret->isa = [OFString class];
- return ret;
+ return element;
}
@end
@implementation OFDictionaryEnumerator
- initWithDictionary: (OFDictionary*)dictionary_
Index: src/OFList.m
==================================================================
--- src/OFList.m
+++ src/OFList.m
@@ -18,10 +18,11 @@
#include "assert.h"
#import "OFList.h"
#import "OFString.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#import "OFEnumerationMutationException.h"
#import "macros.h"
@@ -321,64 +322,52 @@
*/
ret->isa = [OFString class];
return ret;
}
-- (OFString*)stringBySerializing
+- (OFXMLElement*)XMLElementBySerializing
{
- OFMutableString *ret;
OFAutoreleasePool *pool;
+ OFXMLElement *element;
of_list_object_t *iter;
- if (count == 0)
- return @"(list,mutable)[]";
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
- ret = [OFMutableString stringWithString: @"(list,mutable)[\n"];
pool = [[OFAutoreleasePool alloc] init];
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
for (iter = firstListObject; iter != NULL; iter = iter->next) {
- [ret appendString: [iter->object stringBySerializing]];
-
- if (iter->next != NULL)
- [ret appendString: @",\n"];
-
+ [element addChild: [iter->object XMLElementBySerializing]];
[pool releaseObjects];
}
- [ret replaceOccurrencesOfString: @"\n"
- withString: @"\n\t"];
- [ret appendString: @"\n]"];
[pool release];
- /*
- * Class swizzle the string to be immutable. We declared the return type
- * to be OFString*, so it can't be modified anyway. But not swizzling it
- * would create a real copy each time -[copy] is called.
- */
- ret->isa = [OFString class];
- return ret;
+ return element;
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count_
{
- of_list_object_t **list_obj = (of_list_object_t**)state->extra;
+ of_list_object_t **listObject = (of_list_object_t**)state->extra;
state->itemsPtr = objects;
state->mutationsPtr = &mutations;
if (state->state == 0) {
- *list_obj = firstListObject;
+ *listObject = firstListObject;
state->state = 1;
}
- if (*list_obj == NULL)
+ if (*listObject == NULL)
return 0;
- objects[0] = (*list_obj)->object;
- *list_obj = (*list_obj)->next;
+ objects[0] = (*listObject)->object;
+ *listObject = (*listObject)->next;
return 1;
}
- (OFEnumerator*)objectEnumerator
{
Index: src/OFNumber.m
==================================================================
--- src/OFNumber.m
+++ src/OFNumber.m
@@ -18,10 +18,12 @@
#include
#import "OFNumber.h"
#import "OFString.h"
+#import "OFXMLElement.h"
+#import "OFAutoreleasePool.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "macros.h"
@@ -1088,90 +1090,70 @@
default:
@throw [OFInvalidFormatException newWithClass: isa];
}
}
-- (OFString*)stringBySerializing
+- (OFXMLElement*)XMLElementBySerializing
{
+ OFAutoreleasePool *pool;
+ OFXMLElement *element;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
+ pool = [[OFAutoreleasePool alloc] init];
+
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
+ [element setStringValue: [self description]];
+
switch (type) {
case OF_NUMBER_BOOL:
- return (value.bool_ ? @"1" : @"0");
+ [element addAttributeWithName: @"type"
+ stringValue: @"boolean"];
+ break;
case OF_NUMBER_UCHAR:
- return [OFString stringWithFormat: @"%hhu",
- value.uchar];
case OF_NUMBER_USHORT:
- return [OFString stringWithFormat: @"%hu",
- value.ushort];
case OF_NUMBER_UINT:
- return [OFString stringWithFormat: @"%u",
- value.uint];
case OF_NUMBER_ULONG:
- return [OFString stringWithFormat: @"%lu",
- value.ulong];
case OF_NUMBER_UINT8:
- return [OFString stringWithFormat: @"%" @PRIu8,
- value.uint8];
case OF_NUMBER_UINT16:
- return [OFString stringWithFormat: @"%" @PRIu16,
- value.uint16];
case OF_NUMBER_UINT32:
- return [OFString stringWithFormat: @"%" @PRIu32,
- value.uint32];
case OF_NUMBER_UINT64:
- return [OFString stringWithFormat: @"%" @PRIu64,
- value.uint64];
case OF_NUMBER_SIZE:
- return [OFString stringWithFormat: @"%ju",
- (uintmax_t)value.size];
case OF_NUMBER_UINTMAX:
- return [OFString stringWithFormat: @"%ju",
- value.uintmax];
case OF_NUMBER_UINTPTR:
- return [OFString stringWithFormat: @"%" @PRIuPTR,
- value.uintptr];
+ [element addAttributeWithName: @"type"
+ stringValue: @"unsigned"];
+ break;
case OF_NUMBER_CHAR:
- return [OFString stringWithFormat: @"%hhd",
- value.char_];
case OF_NUMBER_SHORT:
- return [OFString stringWithFormat: @"%hd",
- value.short_];
case OF_NUMBER_INT:
- return [OFString stringWithFormat: @"%d",
- value.int_];
case OF_NUMBER_LONG:
- return [OFString stringWithFormat: @"%ld",
- value.long_];
case OF_NUMBER_INT8:
- return [OFString stringWithFormat: @"%" @PRId8,
- value.int8];
case OF_NUMBER_INT16:
- return [OFString stringWithFormat: @"%" @PRId16,
- value.int16];
case OF_NUMBER_INT32:
- return [OFString stringWithFormat: @"%" @PRId32,
- value.int32];
case OF_NUMBER_INT64:
- return [OFString stringWithFormat: @"%" @PRId64,
- value.int64];
case OF_NUMBER_SSIZE:
- return [OFString stringWithFormat: @"%jd",
- (intmax_t)value.ssize];
case OF_NUMBER_INTMAX:
- return [OFString stringWithFormat: @"%jd",
- value.intmax];
case OF_NUMBER_PTRDIFF:
- return [OFString stringWithFormat: @"%td" @PRIdPTR,
- value.ptrdiff];
case OF_NUMBER_INTPTR:
- return [OFString stringWithFormat: @"%" @PRIdPTR,
- value.intptr];
+ [element addAttributeWithName: @"type"
+ stringValue: @"signed"];
+ break;
case OF_NUMBER_FLOAT:
- return [OFString stringWithFormat: @"%f",
- value.float_];
+ [element addAttributeWithName: @"type"
+ stringValue: @"float"];
+ break;
case OF_NUMBER_DOUBLE:
- return [OFString stringWithFormat: @"%lf",
- value.double_];
+ [element addAttributeWithName: @"type"
+ stringValue: @"double"];
+ break;
default:
@throw [OFInvalidFormatException newWithClass: isa];
}
+
+ [pool release];
+
+ return element;
}
@end
Index: src/OFSerialization.h
==================================================================
--- src/OFSerialization.h
+++ src/OFSerialization.h
@@ -13,15 +13,20 @@
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
@class OFString;
+@class OFXMLElement;
+
+#define OF_SERIALIZATION_NS @"https://webkeks.org/objfw/serialization"
/**
* \brief A protocol for serializing objects.
*/
@protocol OFSerialization
/**
- * \brief Serializes the object into a string.
+ * \brief Serializes the object into an XML element.
+ *
+ * \return The object serialized into an XML element
*/
-- (OFString*)stringBySerializing;
+- (OFXMLElement*)XMLElementBySerializing;
@end
Index: src/OFString.m
==================================================================
--- src/OFString.m
+++ src/OFString.m
@@ -34,10 +34,11 @@
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFFile.h"
#import "OFURL.h"
#import "OFHTTPRequest.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#import "OFHTTPRequestFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
@@ -1053,37 +1054,31 @@
- (OFString*)description
{
return [[self copy] autorelease];
}
-- (OFString*)stringBySerializing
-{
- OFMutableString *serialization = [[self mutableCopy] autorelease];
- [serialization replaceOccurrencesOfString: @"\\"
- withString: @"\\\\"];
- [serialization replaceOccurrencesOfString: @"\""
- withString: @"\\\""];
- [serialization replaceOccurrencesOfString: @"\n"
- withString: @"\\n\"\n \""];
- [serialization replaceOccurrencesOfString: @"\r"
- withString: @"\\r"];
- [serialization replaceOccurrencesOfString: @"\t"
- withString: @"\\t"];
-
- if ([self isKindOfClass: [OFMutableString class]])
- [serialization prependString: @"(mutable)\""];
+- (OFXMLElement*)XMLElementBySerializing
+{
+ OFAutoreleasePool *pool;
+ OFXMLElement *element;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: self];
+
+ pool = [[OFAutoreleasePool alloc] init];
+
+ if ([self isKindOfClass: [OFConstantString class]])
+ [element addAttributeWithName: @"class"
+ stringValue: @"OFString"];
else
- [serialization prependString: @"\""];
- [serialization appendString: @"\""];
-
- /*
- * Class swizzle the string to be immutable. We declared the return type
- * to be OFString*, so it can't be modified anyway. But not swizzling it
- * would create a real copy each time -[copy] is called.
- */
- serialization->isa = [OFString class];
- return serialization;
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
+
+ [pool release];
+
+ return element;
}
- (of_unichar_t)characterAtIndex: (size_t)index
{
of_unichar_t c;
Index: src/OFURL.m
==================================================================
--- src/OFURL.m
+++ src/OFURL.m
@@ -21,10 +21,11 @@
#include
#import "OFURL.h"
#import "OFString.h"
#import "OFArray.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
@@ -528,21 +529,24 @@
- (OFString*)description
{
return [self string];
}
-- (OFString*)stringBySerializing
-{
- OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
- OFString *ret = [[OFString alloc]
- initWithFormat: @"(class=OFURL,version=0)<%@>",
- [[self string] stringBySerializing]];
-
- @try {
- [pool release];
- } @finally {
- [ret autorelease];
- }
-
- return ret;
+- (OFXMLElement*)XMLElementBySerializing
+{
+ OFAutoreleasePool *pool;
+ OFXMLElement *element;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
+ pool = [[OFAutoreleasePool alloc] init];
+
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
+ [element setStringValue: [self string]];
+
+ [pool release];
+
+ return element;
}
@end
Index: src/OFXMLAttribute.m
==================================================================
--- src/OFXMLAttribute.m
+++ src/OFXMLAttribute.m
@@ -17,10 +17,11 @@
#include "config.h"
#import "OFXMLAttribute.h"
#import "OFString.h"
#import "OFDictionary.h"
+#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
@implementation OFXMLAttribute
+ attributeWithName: (OFString*)name
namespace: (OFString*)ns
@@ -71,36 +72,37 @@
- (OFString*)stringValue
{
return [[stringValue copy] autorelease];
}
-- (OFString*)stringBySerializing
-{
- OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
- OFMutableDictionary *dictionary = [OFMutableDictionary dictionary];
- OFString *ret;
-
- if (name != nil)
- [dictionary setObject: name
- forKey: @"name"];
- if (ns != nil)
- [dictionary setObject: ns
- forKey: @"namespace"];
- if (stringValue != nil)
- [dictionary setObject: stringValue
- forKey: @"stringValue"];
-
- dictionary->isa = [OFDictionary class];
-
- ret = [[OFString alloc]
- initWithFormat: @"(class=OFXMLElement,version=0)<%@>",
- [dictionary stringBySerializing]];
-
- @try {
- [pool release];
- } @finally {
- [ret autorelease];
- }
-
- return ret;
+- (OFXMLElement*)XMLElementBySerializing
+{
+ OFAutoreleasePool *pool;
+ OFXMLElement *element;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
+ pool = [[OFAutoreleasePool alloc] init];
+
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
+
+ [element addChild:
+ [OFXMLElement elementWithName: @"name"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: name]];
+ if (ns != nil)
+ [element addChild:
+ [OFXMLElement elementWithName: @"namespace"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: ns]];
+ [element addChild:
+ [OFXMLElement elementWithName: @"stringValue"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: stringValue]];
+
+ [pool release];
+
+ return element;
}
@end
Index: src/OFXMLElement.m
==================================================================
--- src/OFXMLElement.m
+++ src/OFXMLElement.m
@@ -566,57 +566,94 @@
- (OFString*)description
{
return [self XMLString];
}
-- (OFString*)stringBySerializing
+- (OFXMLElement*)XMLElementBySerializing
{
- OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
- OFMutableDictionary *dictionary = [OFMutableDictionary dictionary];
- OFString *ret;
+ OFAutoreleasePool *pool;
+ OFXMLElement *element;
+
+ element = [OFXMLElement elementWithName: @"object"
+ namespace: OF_SERIALIZATION_NS];
+
+ pool = [[OFAutoreleasePool alloc] init];
+
+ [element addAttributeWithName: @"class"
+ stringValue: [self className]];
if (name != nil)
- [dictionary setObject: name
- forKey: @"name"];
- if (ns != nil)
- [dictionary setObject: ns
- forKey: @"namespace"];
- if (defaultNamespace != nil)
- [dictionary setObject: defaultNamespace
- forKey: @"defaultNamespace"];
- if (attributes != nil)
- [dictionary setObject: attributes
- forKey: @"attributes"];
- if (namespaces != nil)
- [dictionary setObject: namespaces
- forKey: @"namespaces"];
- if (children != nil)
- [dictionary setObject: children
- forKey: @"children"];
- if (characters != nil)
- [dictionary setObject: characters
- forKey: @"characters"];
- if (CDATA != nil)
- [dictionary setObject: CDATA
- forKey: @"CDATA"];
- if (comment != nil)
- [dictionary setObject: comment
- forKey: @"comment"];
-
- dictionary->isa = [OFDictionary class];
-
- ret = [[OFString alloc]
- initWithFormat: @"(class=OFXMLElement,version=0)<%@>",
- [dictionary stringBySerializing]];
-
- @try {
- [pool release];
- } @finally {
- [ret autorelease];
- }
-
- return ret;
+ [element addChild:
+ [OFXMLElement elementWithName: @"name"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: name]];
+
+ if (ns != nil)
+ [element addChild:
+ [OFXMLElement elementWithName: @"namespace"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: ns]];
+
+ if (defaultNamespace != nil)
+ [element addChild:
+ [OFXMLElement elementWithName: @"defaultNamespace"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: defaultNamespace]];
+
+ if (attributes != nil) {
+ OFXMLElement *attributesElement;
+
+ attributesElement =
+ [OFXMLElement elementWithName: @"attributes"
+ namespace: OF_SERIALIZATION_NS];
+ [attributesElement addChild:
+ [attributes XMLElementBySerializing]];
+ [element addChild: attributesElement];
+ }
+
+ if (namespaces != nil) {
+ OFXMLElement *namespacesElement;
+
+ namespacesElement =
+ [OFXMLElement elementWithName: @"namespaces"
+ namespace: OF_SERIALIZATION_NS];
+ [namespacesElement addChild:
+ [namespaces XMLElementBySerializing]];
+ [element addChild: namespacesElement];
+ }
+
+ if (children != nil) {
+ OFXMLElement *childrenElement;
+
+ childrenElement =
+ [OFXMLElement elementWithName: @"children"
+ namespace: OF_SERIALIZATION_NS];
+ [childrenElement addChild: [children XMLElementBySerializing]];
+ [element addChild: childrenElement];
+ }
+
+ if (characters != nil)
+ [element addChild:
+ [OFXMLElement elementWithName: @"characters"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: characters]];
+
+ if (CDATA != nil)
+ [element addChild:
+ [OFXMLElement elementWithName: @"CDATA"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: CDATA]];
+
+ if (comment != nil)
+ [element addChild:
+ [OFXMLElement elementWithName: @"comment"
+ namespace: OF_SERIALIZATION_NS
+ stringValue: comment]];
+
+ [pool release];
+
+ return element;
}
- (void)addAttribute: (OFXMLAttribute*)attribute
{
if (name == nil)