Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -202,10 +202,12 @@ 4B3D23EB1337FCB000DD29B8 /* unicode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B67998C1099E7C50041064A /* unicode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23EE1337FFD000DD29B8 /* of_asprintf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB50DD012F863C700C9393F /* of_asprintf.m */; }; 4B3D5694139A617D0010A78F /* OFSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3D5693139A617D0010A78F /* OFSerializationTests.m */; }; 4B45355313DCFE1E0037AB4D /* OFCountedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B45355113DCFE1E0037AB4D /* OFCountedSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B45355413DCFE1E0037AB4D /* OFCountedSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B45355213DCFE1E0037AB4D /* OFCountedSet.m */; }; + 4B48B95414DC23B100546D39 /* OFXMLProcessingInstructions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B48B95214DC23B100546D39 /* OFXMLProcessingInstructions.h */; }; + 4B48B95514DC23B100546D39 /* OFXMLProcessingInstructions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B48B95314DC23B100546D39 /* OFXMLProcessingInstructions.m */; }; 4B49EA66143B39CE0005BBC6 /* OFXMLNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B49EA65143B39CE0005BBC6 /* OFXMLNodeTests.m */; }; 4B49EA6D143B3A090005BBC6 /* OFXMLCDATA.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49EA67143B3A090005BBC6 /* OFXMLCDATA.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49EA6E143B3A090005BBC6 /* OFXMLCDATA.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B49EA68143B3A090005BBC6 /* OFXMLCDATA.m */; }; 4B49EA6F143B3A090005BBC6 /* OFXMLCharacters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49EA69143B3A090005BBC6 /* OFXMLCharacters.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49EA70143B3A090005BBC6 /* OFXMLCharacters.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B49EA6A143B3A090005BBC6 /* OFXMLCharacters.m */; }; @@ -477,10 +479,12 @@ 4B3D23BB1337FC5800DD29B8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; 4B3D23EF1338008000DD29B8 /* mach_alias_list */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = mach_alias_list; path = src/mach_alias_list; sourceTree = SOURCE_ROOT; }; 4B3D5693139A617D0010A78F /* OFSerializationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSerializationTests.m; path = tests/OFSerializationTests.m; sourceTree = ""; }; 4B45355113DCFE1E0037AB4D /* OFCountedSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFCountedSet.h; path = src/OFCountedSet.h; sourceTree = ""; }; 4B45355213DCFE1E0037AB4D /* OFCountedSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFCountedSet.m; path = src/OFCountedSet.m; sourceTree = ""; }; + 4B48B95214DC23B100546D39 /* OFXMLProcessingInstructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFXMLProcessingInstructions.h; path = src/OFXMLProcessingInstructions.h; sourceTree = ""; }; + 4B48B95314DC23B100546D39 /* OFXMLProcessingInstructions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLProcessingInstructions.m; path = src/OFXMLProcessingInstructions.m; sourceTree = ""; }; 4B4986DF1101F64500A2CFDA /* objc_properties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = objc_properties.m; path = src/objc_properties.m; sourceTree = ""; }; 4B49EA65143B39CE0005BBC6 /* OFXMLNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLNodeTests.m; path = tests/OFXMLNodeTests.m; sourceTree = ""; }; 4B49EA67143B3A090005BBC6 /* OFXMLCDATA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFXMLCDATA.h; path = src/OFXMLCDATA.h; sourceTree = ""; }; 4B49EA68143B3A090005BBC6 /* OFXMLCDATA.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLCDATA.m; path = src/OFXMLCDATA.m; sourceTree = ""; }; 4B49EA69143B3A090005BBC6 /* OFXMLCharacters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFXMLCharacters.h; path = src/OFXMLCharacters.h; sourceTree = ""; }; @@ -1011,10 +1015,12 @@ 4B0D249511DFAA3D00ED6FFC /* OFXMLElementBuilder.m */, 4B11005A14329B9A003A45D8 /* OFXMLNode.h */, 4B11005B14329B9A003A45D8 /* OFXMLNode.m */, 4B6799891099E7C50041064A /* OFXMLParser.h */, 4B67998A1099E7C50041064A /* OFXMLParser.m */, + 4B48B95214DC23B100546D39 /* OFXMLProcessingInstructions.h */, + 4B48B95314DC23B100546D39 /* OFXMLProcessingInstructions.m */, 4B6AF97310A8D4450003FB0A /* ObjFW.h */, 4B6799561099E7C50041064A /* asprintf.h */, 4B6AF96C10A8D3E40003FB0A /* asprintf.m */, 4BBA36C411406AB700CBA3AC /* atomic.h */, 4B3D236D1337FB5800DD29B8 /* base64.h */, @@ -1253,10 +1259,11 @@ 4B83F0F4142FDEFD00E4A821 /* OFStreamObserver_kqueue.h in Headers */, 4B64D6EF1425381E007BDFB1 /* OFStreamObserver_poll.h in Headers */, 4B64D6F11425381E007BDFB1 /* OFStreamObserver_select.h in Headers */, 4B552554147AA5DB0003BF47 /* OFString_UTF8.h in Headers */, 4BD653C5143B8489006182F0 /* OFTCPSocket+SOCKS5.h in Headers */, + 4B48B95414DC23B100546D39 /* OFXMLProcessingInstructions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ @@ -1528,10 +1535,11 @@ 4B55A104133ABEA900B58A93 /* OFThreadStillRunningException.m in Sources */, 4B17FFAA133A34E7003E6DCD /* OFTruncatedDataException.m in Sources */, 4B17FFB6133A375B003E6DCD /* OFUnboundNamespaceException.m in Sources */, 4B17FFB2133A3664003E6DCD /* OFUnsupportedProtocolException.m in Sources */, 4B55A117133AC24600B58A93 /* OFWriteFailedException.m in Sources */, + 4B48B95514DC23B100546D39 /* OFXMLProcessingInstructions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BF33AEC133807310059CEF7 /* Sources */ = { isa = PBXSourcesBuildPhase; Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -58,10 +58,11 @@ OFXMLElement.m \ OFXMLElement+Serialization.m \ OFXMLElementBuilder.m \ OFXMLNode.m \ OFXMLParser.m \ + OFXMLProcessingInstructions.m \ base64.m \ of_asprintf.m \ of_strptime.m \ unicode.m Index: src/OFXMLElementBuilder.m ================================================================== --- src/OFXMLElementBuilder.m +++ src/OFXMLElementBuilder.m @@ -22,10 +22,11 @@ #import "OFXMLElement.h" #import "OFXMLAttribute.h" #import "OFXMLCharacters.h" #import "OFXMLCDATA.h" #import "OFXMLComment.h" +#import "OFXMLProcessingInstructions.h" #import "OFXMLParser.h" #import "OFMutableArray.h" #import "OFMalformedXMLException.h" @@ -69,10 +70,19 @@ } - (void)parser: (OFXMLParser*)parser foundProcessingInstructions: (OFString*)pi { + OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions + processingInstructionsWithString: pi]; + OFXMLElement *parent = [stack lastObject]; + + if (parent != nil) + [parent addChild: node]; + else + [delegate elementBuilder: self + didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser*)parser didStartElement: (OFString*)name withPrefix: (OFString*)prefix ADDED src/OFXMLProcessingInstructions.h Index: src/OFXMLProcessingInstructions.h ================================================================== --- src/OFXMLProcessingInstructions.h +++ src/OFXMLProcessingInstructions.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFXMLNode.h" + +/** + * \brief A class for representing XML processing instructions. + */ +@interface OFXMLProcessingInstructions: OFXMLNode +{ + OFString *processingInstructions; +} + +/** + * \brief Creates a new OFXMLProcessingInstructions with the specified string. + * + * \param string The string for the processing instructions + * \return A new OFXMLProcessingInstructions + */ ++ processingInstructionsWithString: (OFString*)string; + +/** + * \brief Initializes an already allocated OFXMLProcessingInstructions with the + * specified string. + * + * \param string The string for the processing instructions + * \return An initialized OFXMLProcessingInstructions + */ +- initWithString: (OFString*)string; +@end ADDED src/OFXMLProcessingInstructions.m Index: src/OFXMLProcessingInstructions.m ================================================================== --- src/OFXMLProcessingInstructions.m +++ src/OFXMLProcessingInstructions.m @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include + +#import "OFXMLProcessingInstructions.h" +#import "OFString.h" +#import "OFXMLElement.h" +#import "OFAutoreleasePool.h" + +#import "OFInvalidArgumentException.h" + +@implementation OFXMLProcessingInstructions ++ processingInstructionsWithString: (OFString*)string +{ + return [[[self alloc] initWithString: string] autorelease]; +} + +- initWithString: (OFString*)string +{ + self = [super init]; + + @try { + processingInstructions = [string copy]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithSerialization: (OFXMLElement*)element +{ + self = [super init]; + + @try { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + + if (![[element name] isEqual: [self className]] || + ![[element namespace] isEqual: OF_SERIALIZATION_NS]) + @throw [OFInvalidArgumentException + exceptionWithClass: isa + selector: _cmd]; + + processingInstructions = [[element stringValue] copy]; + + [pool release]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (BOOL)isEqual: (id)object +{ + OFXMLProcessingInstructions *otherProcessingInstructions; + + if (![object isKindOfClass: [OFXMLProcessingInstructions class]]) + return NO; + + otherProcessingInstructions = object; + + return ([otherProcessingInstructions->processingInstructions + isEqual: processingInstructions]); +} + +- (uint32_t)hash +{ + return [processingInstructions hash]; +} + +- (OFString*)stringValue +{ + return @""; +} + +- (OFString*)XMLString +{ + return [OFString stringWithFormat: @"", processingInstructions]; +} + +- (OFString*)XMLStringWithIndentation: (unsigned int)indentation +{ + return [OFString stringWithFormat: @"", processingInstructions]; +} + +- (OFString*)XMLStringWithIndentation: (unsigned int)indentation + level: (unsigned int)level +{ + OFString *ret; + + if (indentation > 0 && level > 0) { + char *whitespaces = [self allocMemoryWithSize: + (level * indentation) + 1]; + memset(whitespaces, ' ', level * indentation); + whitespaces[level * indentation] = 0; + + @try { + ret = [OFString stringWithFormat: + @"%s", + whitespaces, + processingInstructions]; + } @finally { + [self freeMemory: whitespaces]; + } + } else + ret = [OFString stringWithFormat: @"", + processingInstructions]; + + return ret; +} + +- (OFString*)description +{ + return [OFString stringWithFormat: @"", processingInstructions]; +} + +- (OFXMLElement*)XMLElementBySerializing +{ + return [OFXMLElement elementWithName: [self className] + namespace: OF_SERIALIZATION_NS + stringValue: processingInstructions]; +} +@end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -59,10 +59,11 @@ #import "OFXMLElement.h" #import "OFXMLAttribute.h" #import "OFXMLCharacters.h" #import "OFXMLCDATA.h" #import "OFXMLComment.h" +#import "OFXMLProcessingInstructions.h" #import "OFXMLParser.h" #import "OFXMLElementBuilder.h" #import "OFSerialization.h" Index: tests/OFXMLElementBuilderTests.m ================================================================== --- tests/OFXMLElementBuilderTests.m +++ tests/OFXMLElementBuilderTests.m @@ -48,11 +48,11 @@ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFXMLParser *p = [OFXMLParser parser]; OFXMLElementBuilder *builder = [OFXMLElementBuilder elementBuilder]; OFString *str = @"barbaz" - " " + " " ""; [p setDelegate: builder]; [builder setDelegate: self];