Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -202,11 +202,11 @@ 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 */; }; + 4B48B95414DC23B100546D39 /* OFXMLProcessingInstructions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B48B95214DC23B100546D39 /* OFXMLProcessingInstructions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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, ); }; }; @@ -232,11 +232,10 @@ 4B55A113133AC24600B58A93 /* OFReadFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55A10D133AC24500B58A93 /* OFReadFailedException.m */; }; 4B55A114133AC24600B58A93 /* OFReadOrWriteFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B55A10E133AC24500B58A93 /* OFReadOrWriteFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B55A115133AC24600B58A93 /* OFReadOrWriteFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55A10F133AC24500B58A93 /* OFReadOrWriteFailedException.m */; }; 4B55A116133AC24600B58A93 /* OFWriteFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B55A110133AC24500B58A93 /* OFWriteFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B55A117133AC24600B58A93 /* OFWriteFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55A111133AC24600B58A93 /* OFWriteFailedException.m */; }; - 4B5CF8F814940BD2007AA324 /* OFJSONEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5CF8F514940BD2007AA324 /* OFJSONEncoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5CF8F914940BD2007AA324 /* OFString+JSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5CF8F614940BD2007AA324 /* OFString+JSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5CF8FA14940BD2007AA324 /* OFString+JSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5CF8F714940BD2007AA324 /* OFString+JSONValue.m */; }; 4B64D6EF1425381E007BDFB1 /* OFStreamObserver_poll.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B64D6EB1425381E007BDFB1 /* OFStreamObserver_poll.h */; }; 4B64D6F01425381E007BDFB1 /* OFStreamObserver_poll.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B64D6EC1425381E007BDFB1 /* OFStreamObserver_poll.m */; }; 4B64D6F11425381E007BDFB1 /* OFStreamObserver_select.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B64D6ED1425381E007BDFB1 /* OFStreamObserver_select.h */; }; @@ -275,10 +274,12 @@ 4B989C2F13771A3700109A30 /* OFSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B989C2E13771A3700109A30 /* OFSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9BB7BD141CDE2D000AD1CC /* OFArray_adjacentSubarray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9BB7B9141CDE2D000AD1CC /* OFArray_adjacentSubarray.h */; }; 4B9BB7BE141CDE2D000AD1CC /* OFArray_adjacentSubarray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BB7BA141CDE2D000AD1CC /* OFArray_adjacentSubarray.m */; }; 4B9BB7BF141CDE2D000AD1CC /* OFArray_subarray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9BB7BB141CDE2D000AD1CC /* OFArray_subarray.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9BB7C0141CDE2D000AD1CC /* OFArray_subarray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BB7BC141CDE2D000AD1CC /* OFArray_subarray.m */; }; + 4BA02BA115041F5900002F84 /* OFJSONRepresentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA02B9F15041F5900002F84 /* OFJSONRepresentation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA02BA215041F5900002F84 /* OFTLSSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA02BA015041F5900002F84 /* OFTLSSocket.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA355BA14879BDD00442EF4 /* of_strptime.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA355B914879BDD00442EF4 /* of_strptime.m */; }; 4BA355BD14879BF700442EF4 /* of_strptime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA355BC14879BF700442EF4 /* of_strptime.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA49D9013DB113B00381CDB /* OFIntrospection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA49D8E13DB113B00381CDB /* OFIntrospection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA49D9113DB113B00381CDB /* OFIntrospection.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA49D8F13DB113B00381CDB /* OFIntrospection.m */; }; 4BA85BCA140ECCE800E91D51 /* OFCountedSet_hashtable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA85BC4140ECCE800E91D51 /* OFCountedSet_hashtable.h */; }; @@ -512,11 +513,10 @@ 4B55A10D133AC24500B58A93 /* OFReadFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFReadFailedException.m; path = src/exceptions/OFReadFailedException.m; sourceTree = ""; }; 4B55A10E133AC24500B58A93 /* OFReadOrWriteFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFReadOrWriteFailedException.h; path = src/exceptions/OFReadOrWriteFailedException.h; sourceTree = ""; }; 4B55A10F133AC24500B58A93 /* OFReadOrWriteFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFReadOrWriteFailedException.m; path = src/exceptions/OFReadOrWriteFailedException.m; sourceTree = ""; }; 4B55A110133AC24500B58A93 /* OFWriteFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFWriteFailedException.h; path = src/exceptions/OFWriteFailedException.h; sourceTree = ""; }; 4B55A111133AC24600B58A93 /* OFWriteFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFWriteFailedException.m; path = src/exceptions/OFWriteFailedException.m; sourceTree = ""; }; - 4B5CF8F514940BD2007AA324 /* OFJSONEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFJSONEncoding.h; path = src/OFJSONEncoding.h; sourceTree = ""; }; 4B5CF8F614940BD2007AA324 /* OFString+JSONValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFString+JSONValue.h"; path = "src/OFString+JSONValue.h"; sourceTree = ""; }; 4B5CF8F714940BD2007AA324 /* OFString+JSONValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFString+JSONValue.m"; path = "src/OFString+JSONValue.m"; sourceTree = ""; }; 4B64D6EB1425381E007BDFB1 /* OFStreamObserver_poll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamObserver_poll.h; path = src/OFStreamObserver_poll.h; sourceTree = ""; }; 4B64D6EC1425381E007BDFB1 /* OFStreamObserver_poll.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamObserver_poll.m; path = src/OFStreamObserver_poll.m; sourceTree = ""; }; 4B64D6ED1425381E007BDFB1 /* OFStreamObserver_select.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamObserver_select.h; path = src/OFStreamObserver_select.h; sourceTree = ""; }; @@ -626,10 +626,12 @@ 4B99251012E0780000215DBE /* OFHTTPRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFHTTPRequest.m; path = src/OFHTTPRequest.m; sourceTree = ""; }; 4B9BB7B9141CDE2D000AD1CC /* OFArray_adjacentSubarray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFArray_adjacentSubarray.h; path = src/OFArray_adjacentSubarray.h; sourceTree = ""; }; 4B9BB7BA141CDE2D000AD1CC /* OFArray_adjacentSubarray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFArray_adjacentSubarray.m; path = src/OFArray_adjacentSubarray.m; sourceTree = ""; }; 4B9BB7BB141CDE2D000AD1CC /* OFArray_subarray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFArray_subarray.h; path = src/OFArray_subarray.h; sourceTree = ""; }; 4B9BB7BC141CDE2D000AD1CC /* OFArray_subarray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFArray_subarray.m; path = src/OFArray_subarray.m; sourceTree = ""; }; + 4BA02B9F15041F5900002F84 /* OFJSONRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFJSONRepresentation.h; path = src/OFJSONRepresentation.h; sourceTree = ""; }; + 4BA02BA015041F5900002F84 /* OFTLSSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFTLSSocket.h; path = src/OFTLSSocket.h; sourceTree = ""; }; 4BA355B914879BDD00442EF4 /* of_strptime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = of_strptime.m; path = src/of_strptime.m; sourceTree = ""; }; 4BA355BC14879BF700442EF4 /* of_strptime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = of_strptime.h; path = src/of_strptime.h; sourceTree = ""; }; 4BA49D8E13DB113B00381CDB /* OFIntrospection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFIntrospection.h; path = src/OFIntrospection.h; sourceTree = ""; }; 4BA49D8F13DB113B00381CDB /* OFIntrospection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFIntrospection.m; path = src/OFIntrospection.m; sourceTree = ""; }; 4BA85BC4140ECCE800E91D51 /* OFCountedSet_hashtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFCountedSet_hashtable.h; path = src/OFCountedSet_hashtable.h; sourceTree = ""; }; @@ -919,11 +921,11 @@ 4BF1BCC111C9663F0025511F /* OFHash.m */, 4B99250F12E0780000215DBE /* OFHTTPRequest.h */, 4B99251012E0780000215DBE /* OFHTTPRequest.m */, 4BA49D8E13DB113B00381CDB /* OFIntrospection.h */, 4BA49D8F13DB113B00381CDB /* OFIntrospection.m */, - 4B5CF8F514940BD2007AA324 /* OFJSONEncoding.h */, + 4BA02B9F15041F5900002F84 /* OFJSONRepresentation.h */, 4B67996C1099E7C50041064A /* OFList.h */, 4B67996D1099E7C50041064A /* OFList.m */, 4BF1BCC211C9663F0025511F /* OFMD5Hash.h */, 4BF1BCC311C9663F0025511F /* OFMD5Hash.m */, 4B67996F1099E7C50041064A /* OFMutableArray.h */, @@ -995,10 +997,11 @@ 4B6799821099E7C50041064A /* OFTCPSocket.m */, 4BD653C3143B8489006182F0 /* OFTCPSocket+SOCKS5.h */, 4BD653C4143B8489006182F0 /* OFTCPSocket+SOCKS5.m */, 4B6799831099E7C50041064A /* OFThread.h */, 4B6799841099E7C50041064A /* OFThread.m */, + 4BA02BA015041F5900002F84 /* OFTLSSocket.h */, 4B4A61F212DF5EA20048F3F2 /* OFURL.h */, 4B4A61F312DF5EA20048F3F2 /* OFURL.m */, 4BF1BCCE11C9663F0025511F /* OFXMLAttribute.h */, 4BF1BCCF11C9663F0025511F /* OFXMLAttribute.m */, 4B49EA67143B3A090005BBC6 /* OFXMLCDATA.h */, @@ -1144,11 +1147,11 @@ 4B17FF74133A2AAB003E6DCD /* OFException.h in Headers */, 4B3D23C81337FCB000DD29B8 /* OFFile.h in Headers */, 4B3D23C91337FCB000DD29B8 /* OFHash.h in Headers */, 4B3D23CA1337FCB000DD29B8 /* OFHTTPRequest.h in Headers */, 4BA49D9013DB113B00381CDB /* OFIntrospection.h in Headers */, - 4B5CF8F814940BD2007AA324 /* OFJSONEncoding.h in Headers */, + 4BA02BA115041F5900002F84 /* OFJSONRepresentation.h in Headers */, 4B3D23CB1337FCB000DD29B8 /* OFList.h in Headers */, 4B3D23CC1337FCB000DD29B8 /* OFMD5Hash.h in Headers */, 4B3D23CD1337FCB000DD29B8 /* OFMutableArray.h in Headers */, 4B3D23CE1337FCB000DD29B8 /* OFMutableDictionary.h in Headers */, 4B39844713D3AFB400E6F825 /* OFMutableSet.h in Headers */, @@ -1173,10 +1176,11 @@ 4B3D23DA1337FCB000DD29B8 /* OFString+URLEncoding.h in Headers */, 4B3D23DB1337FCB000DD29B8 /* OFString+XMLEscaping.h in Headers */, 4B3D23DC1337FCB000DD29B8 /* OFString+XMLUnescaping.h in Headers */, 4B3D23DD1337FCB000DD29B8 /* OFTCPSocket.h in Headers */, 4B3D23DE1337FCB000DD29B8 /* OFThread.h in Headers */, + 4BA02BA215041F5900002F84 /* OFTLSSocket.h in Headers */, 4B3D23DF1337FCB000DD29B8 /* OFURL.h in Headers */, 4B3D23E01337FCB000DD29B8 /* OFXMLAttribute.h in Headers */, 4B49EA6D143B3A090005BBC6 /* OFXMLCDATA.h in Headers */, 4B49EA6F143B3A090005BBC6 /* OFXMLCharacters.h in Headers */, 4B49EA71143B3A090005BBC6 /* OFXMLComment.h in Headers */, @@ -1183,10 +1187,11 @@ 4B3D23E11337FCB000DD29B8 /* OFXMLElement.h in Headers */, 4BB25E8C139C388A00F574EA /* OFXMLElement+Serialization.h in Headers */, 4B3D23E21337FCB000DD29B8 /* OFXMLElementBuilder.h in Headers */, 4B11005C14329B9A003A45D8 /* OFXMLNode.h in Headers */, 4B3D23E31337FCB000DD29B8 /* OFXMLParser.h in Headers */, + 4B48B95414DC23B100546D39 /* OFXMLProcessingInstructions.h in Headers */, 4B3D23E41337FCB000DD29B8 /* ObjFW.h in Headers */, 4B3D23E51337FCB000DD29B8 /* asprintf.h in Headers */, 4B3D23E61337FCB000DD29B8 /* atomic.h in Headers */, 4B3D23E71337FCB000DD29B8 /* base64.h in Headers */, 4B3D23E81337FCB000DD29B8 /* macros.h in Headers */, @@ -1259,11 +1264,10 @@ 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 */ @@ -1307,12 +1311,12 @@ }; 4BF33AEF133807310059CEF7 /* Tests */ = { isa = PBXNativeTarget; buildConfigurationList = 4BF33AF6133807310059CEF7 /* Build configuration list for PBXNativeTarget "Tests" */; buildPhases = ( - 4BF33AEC133807310059CEF7 /* Sources */, 4BF33AED133807310059CEF7 /* Frameworks */, + 4BF33AEC133807310059CEF7 /* Sources */, 4BF33AEE133807310059CEF7 /* CopyFiles */, 4BF33B4013380CA40059CEF7 /* CopyFiles */, ); buildRules = ( ); @@ -1477,10 +1481,11 @@ 4B3D23AF1337FC0D00DD29B8 /* OFXMLElement.m in Sources */, 4BB25E8D139C388A00F574EA /* OFXMLElement+Serialization.m in Sources */, 4B3D23B01337FC0D00DD29B8 /* OFXMLElementBuilder.m in Sources */, 4B11005D14329B9A003A45D8 /* OFXMLNode.m in Sources */, 4B3D23B11337FC0D00DD29B8 /* OFXMLParser.m in Sources */, + 4B48B95514DC23B100546D39 /* OFXMLProcessingInstructions.m in Sources */, 4B3D23B31337FC0D00DD29B8 /* base64.m in Sources */, 4B3D23B41337FC0D00DD29B8 /* iso_8859_15.m in Sources */, 4B3D23B51337FC0D00DD29B8 /* foundation-compat.m in Sources */, 4B3D23EE1337FFD000DD29B8 /* of_asprintf.m in Sources */, 4BA355BA14879BDD00442EF4 /* of_strptime.m in Sources */, @@ -1535,11 +1540,10 @@ 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; @@ -1549,10 +1553,11 @@ 4BF33AFD133807A20059CEF7 /* OFBlockTests.m in Sources */, 4BF33AFE133807A20059CEF7 /* OFDataArrayTests.m in Sources */, 4BF33AFF133807A20059CEF7 /* OFDateTests.m in Sources */, 4BF33B00133807A20059CEF7 /* OFDictionaryTests.m in Sources */, 4BF33B02133807A20059CEF7 /* OFHTTPRequestTests.m in Sources */, + 4BAA60C814D09699006F068D /* OFJSONTests.m in Sources */, 4BF33B03133807A20059CEF7 /* OFListTests.m in Sources */, 4BF33B04133807A20059CEF7 /* OFMD5HashTests.m in Sources */, 4BF33B05133807A20059CEF7 /* OFNumberTests.m in Sources */, 4BF33B06133807A20059CEF7 /* OFObjectTests.m in Sources */, 4BF33B07133807A20059CEF7 /* OFPluginTests.m in Sources */, @@ -1567,11 +1572,10 @@ 4BF33B0E133807A20059CEF7 /* OFXMLElementBuilderTests.m in Sources */, 4B49EA66143B39CE0005BBC6 /* OFXMLNodeTests.m in Sources */, 4BF33B10133807A20059CEF7 /* OFXMLParserTests.m in Sources */, 4BF33B11133807A20059CEF7 /* PropertiesTests.m in Sources */, 4BF33B12133807A20059CEF7 /* TestsAppDelegate.m in Sources */, - 4BAA60C814D09699006F068D /* OFJSONTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -1,9 +1,9 @@ OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@ OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@ -OBJFW_LIB_MAJOR = 5 -OBJFW_LIB_MINOR = 1 +OBJFW_LIB_MAJOR = 6 +OBJFW_LIB_MINOR = 0 OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR} ASPRINTF_M = @ASPRINTF_M@ ATOMIC_H = @ATOMIC_H@ BIN_PREFIX = @BIN_PREFIX@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -68,10 +68,11 @@ INCLUDES := ${SRCS:.m=.h} \ OFCollection.h \ OFJSONRepresentation.h \ OFSerialization.h \ + OFTLSSocket.h \ ObjFW.h \ asprintf.h \ ${ATOMIC_H} \ macros.h \ objfw-defs.h \ Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -374,20 +374,10 @@ * * \return A description for the class, which is usually the class name */ + (OFString*)description; -/** - * \brief Replaces a class method implementation with another implementation. - * - * \param newImp The new implementation for the class method - * \param selector The selector of the class method to replace - * \return The old implementation - */ -+ (IMP)setImplementation: (IMP)newImp - forClassMethod: (SEL)selector; - /** * \brief Replaces a class method with a class method from another class. * * \param selector The selector of the class method to replace * \param class_ The class from which the new class method should be taken @@ -394,21 +384,10 @@ * \return The old implementation */ + (IMP)replaceClassMethod: (SEL)selector withMethodFromClass: (Class)class_; -/** - * \brief Replaces an instance method implementation with another - * implementation. - * - * \param newImp The new implementation for the instance method - * \param selector The selector of the instance method to replace - * \return The old implementation - */ -+ (IMP)setImplementation: (IMP)newImp - forInstanceMethod: (SEL)selector; - /** * \brief Replaces an instance method with an instance method from another * class. * * \param selector The selector of the instance method to replace @@ -417,40 +396,40 @@ */ + (IMP)replaceInstanceMethod: (SEL)selector withMethodFromClass: (Class)class_; /** - * \brief Adds a class method to the class. - * - * If the method already exists, nothing is done and NO is returned. If you want - * to change the implementation of a method, use - * setImplementation:forClassMethod:. - * - * \param selector The selector for the new method - * \param typeEncoding The type encoding for the new method - * \param implementation The implementation for the new method - * \return Whether the method has been added - */ -+ (BOOL)addClassMethod: (SEL)selector - withTypeEncoding: (const char*)typeEncoding - implementation: (IMP)implementation; - -/** - * \brief Adds an instance method to the class. - * - * If the method already exists, nothing is done and NO is returned. If you want - * to change the implementation of a method, use - * setImplementation:forInstanceMethod:. - * - * \param selector The selector for the new method - * \param typeEncoding The type encoding for the new method - * \param implementation The implementation for the new method - * \return Whether the method has been added - */ -+ (BOOL)addInstanceMethod: (SEL)selector - withTypeEncoding: (const char*)typeEncoding - implementation: (IMP)implementation; + * \brief Replaces or adds a class method. + * + * If the method already exists, it is replaced and the old implementation + * returned. If the method does not exist, it is added with the specified type + * encoding. + * + * \param selector The selector for the new method + * \param implementation The implementation for the new method + * \param typeEncoding The type encoding for the new method + * \return The old implementation or nil if the method was added + */ ++ (IMP)replaceClassMethod: (SEL)selector + withImplementation: (IMP)implementation + typeEncoding: (const char*)typeEncoding; + +/** + * \brief Replaces or adds an instance method. + * + * If the method already exists, it is replaced and the old implementation + * returned. If the method does not exist, it is added with the specified type + * encoding. + * + * \param selector The selector for the new method + * \param implementation The implementation for the new method + * \param typeEncoding The type encoding for the new method + * \return The old implementation or nil if the method was added + */ ++ (IMP)replaceInstanceMethod: (SEL)selector + withImplementation: (IMP)implementation + typeEncoding: (const char*)typeEncoding; /** * \brief Adds all methods from the specified class to the class that is the * receiver. * Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -185,14 +185,12 @@ + alloc { OFObject *instance; size_t instanceSize = class_getInstanceSize(self); - Class class; - void (*last)(id, SEL) = NULL; - if ((instance = malloc(instanceSize + PRE_IVAR_ALIGN)) == NULL) { + if ((instance = calloc(instanceSize + PRE_IVAR_ALIGN, 1)) == NULL) { alloc_failed_exception.isa = [OFAllocFailedException class]; @throw (OFAllocFailedException*)&alloc_failed_exception; } ((struct pre_ivar*)instance)->memoryChunks = NULL; @@ -207,26 +205,12 @@ exceptionWithClass: self]; } #endif instance = (OFObject*)((char*)instance + PRE_IVAR_ALIGN); - memset(instance, 0, instanceSize); instance->isa = self; - for (class = self; class != Nil; class = class_getSuperclass(class)) { - void (*construct)(id, SEL); - - if ([class instancesRespondToSelector: cxx_construct]) { - if ((construct = (void(*)(id, SEL))[class - instanceMethodForSelector: cxx_construct]) != last) - construct(instance, cxx_construct); - - last = construct; - } else - break; - } - return instance; } + new { @@ -311,105 +295,52 @@ + (OFString*)description { return [self className]; } -+ (IMP)setImplementation: (IMP)newImp - forClassMethod: (SEL)selector -{ -#if defined(OF_OBJFW_RUNTIME) - if (newImp == (IMP)0 || !class_respondsToSelector(self->isa, selector)) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; - - return objc_replace_class_method(self, selector, newImp); -#else - Method method; - - if (newImp == (IMP)0 || - (method = class_getClassMethod(self, selector)) == NULL) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; - - /* - * Cast needed because it's isa in the Apple runtime, but class_pointer - * in the GNU runtime. - */ - return class_replaceMethod(((OFObject*)self)->isa, selector, newImp, - method_getTypeEncoding(method)); -#endif -} - + (IMP)replaceClassMethod: (SEL)selector withMethodFromClass: (Class)class { IMP newImp; - - if (![class isSubclassOfClass: self]) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; + const char *typeEncoding; newImp = [class methodForSelector: selector]; - - return [self setImplementation: newImp - forClassMethod: selector]; -} - -+ (IMP)setImplementation: (IMP)newImp - forInstanceMethod: (SEL)selector -{ -#if defined(OF_OBJFW_RUNTIME) - if (newImp == (IMP)0 || !class_respondsToSelector(self, selector)) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; - - return objc_replace_instance_method(self, selector, newImp); -#else - Method method; - - if (newImp == (IMP)0 || - (method = class_getInstanceMethod(self, selector)) == NULL) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; - - return class_replaceMethod(self, selector, newImp, - method_getTypeEncoding(method)); -#endif + typeEncoding = [class typeEncodingForSelector: selector]; + + return [self replaceClassMethod: selector + withImplementation: newImp + typeEncoding: typeEncoding]; } + (IMP)replaceInstanceMethod: (SEL)selector withMethodFromClass: (Class)class { IMP newImp; - - if (![class isSubclassOfClass: self]) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; + const char *typeEncoding; newImp = [class instanceMethodForSelector: selector]; - - return [self setImplementation: newImp - forInstanceMethod: selector]; -} - -+ (BOOL)addInstanceMethod: (SEL)selector - withTypeEncoding: (const char*)typeEncoding - implementation: (IMP)implementation -{ -#if defined(OF_APPLE_RUNTIME) - return class_addMethod(self, selector, implementation, typeEncoding); -#endif -} - -+ (BOOL)addClassMethod: (SEL)selector - withTypeEncoding: (const char*)typeEncoding - implementation: (IMP)implementation -{ -#if defined(OF_APPLE_RUNTIME) - return class_addMethod(((OFObject*)self)->isa, selector, implementation, + typeEncoding = [class typeEncodingForInstanceSelector: selector]; + + return [self replaceInstanceMethod: selector + withImplementation: newImp + typeEncoding: typeEncoding]; +} + ++ (IMP)replaceInstanceMethod: (SEL)selector + withImplementation: (IMP)implementation + typeEncoding: (const char*)typeEncoding +{ + return class_replaceMethod(self, selector, implementation, typeEncoding); -#endif +} + ++ (IMP)replaceClassMethod: (SEL)selector + withImplementation: (IMP)implementation + typeEncoding: (const char*)typeEncoding +{ + return class_replaceMethod(((OFObject*)self)->isa, selector, + implementation, typeEncoding); } + (void)inheritMethodsFromClass: (Class)class { Class superclass = [self superclass]; @@ -423,62 +354,39 @@ methodList = class_copyMethodList(((OFObject*)class)->isa, &count); @try { for (i = 0; i < count; i++) { SEL selector = method_getName(methodList[i]); - IMP implementation; /* * Don't replace methods implemented in receiving class. */ if ([self methodForSelector: selector] != [superclass methodForSelector: selector]) continue; - implementation = [class methodForSelector: selector]; - - if ([self respondsToSelector: selector]) - [self setImplementation: implementation - forClassMethod: selector]; - else { - const char *typeEncoding = - method_getTypeEncoding(methodList[i]); - [self addClassMethod: selector - withTypeEncoding: typeEncoding - implementation: implementation]; - } + [self replaceClassMethod: selector + withMethodFromClass: class]; } } @finally { free(methodList); } methodList = class_copyMethodList(class, &count); @try { for (i = 0; i < count; i++) { SEL selector = method_getName(methodList[i]); - IMP implementation; /* * Don't replace methods implemented in receiving class. */ if ([self instanceMethodForSelector: selector] != [superclass instanceMethodForSelector: selector]) continue; - implementation = - [class instanceMethodForSelector: selector]; - - if ([self instancesRespondToSelector: selector]) - [self setImplementation: implementation - forInstanceMethod: selector]; - else { - const char *typeEncoding = - method_getTypeEncoding(methodList[i]); - [self addInstanceMethod: selector - withTypeEncoding: typeEncoding - implementation: implementation]; - } + [self replaceInstanceMethod: selector + withMethodFromClass: class]; } } @finally { free(methodList); } #else @@ -488,10 +396,26 @@ [self inheritMethodsFromClass: [class superclass]]; } - init { + Class class; + void (*last)(id, SEL) = NULL; + + for (class = isa; class != Nil; class = class_getSuperclass(class)) { + void (*construct)(id, SEL); + + if ([class instancesRespondToSelector: cxx_construct]) { + if ((construct = (void(*)(id, SEL))[class + instanceMethodForSelector: cxx_construct]) != last) + construct(self, cxx_construct); + + last = construct; + } else + break; + } + return self; } - (Class)class { ADDED src/OFTLSSocket.h Index: src/OFTLSSocket.h ================================================================== --- src/OFTLSSocket.h +++ src/OFTLSSocket.h @@ -0,0 +1,112 @@ +/* + * 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 "objfw-defs.h" + +@class OFString; +@class OFArray; +@protocol OFTLSSocket; + +/** + * \brief A delegate for classes implementing the OFTLSSocket protocol. + */ +@protocol OFTLSSocketDelegate +/** + * \brief This callback is called when the TLS socket wants to know if it + * should accept the received keychain. + * + * \param certificate An array of objects implementing the OFX509Certificate + * protocol + * \return Whether the TLS socket should accept the received keychain + */ +- (BOOL)socket: (id )socket + shouldAcceptKeychain: (OFArray*)keychain; +@end + +/** + * \brief A protocol that should be implemented by 3rd party libraries + * implementing TLS. + */ +@protocol OFTLSSocket +#ifdef OF_HAVE_PROPERTIES +@property (assign) id delegate; +@property (copy) OFString *certificateFile, *privateKeyFile; +@property const char *privateKeyPassphrase; +#endif + +/** + * \brief Sets a delegate for the TLS socket. + * + * \param delegate The delegate to use + */ +- (void)setDelegate: (id )delegate; + +/** + * \brief Returns the delegate used by the TLS socket. + * + * \return The delegate used by the TLS socket + */ +- (id )delegate; + +/** + * \brief Sets the path to the X.509 certificate file to use. + * + * \param certificateFile The path to the X.509 certificate file + */ +- (void)setCertificateFile: (OFString*)certificateFile; + +/** + * \brief Returns the path of the X.509 certificate file used by the TLS socket. + * + * \return The path of the X.509 certificate file used by the TLS socket + */ +- (OFString*)certificateFile; + +/** + * \brief Sets the path to the PKCS#8 private key file to use. + * + * \param privateKeyFile The path to the PKCS#8 private key file + */ +- (void)setPrivateKeyFile: (OFString*)privateKeyFile; + +/** + * \brief Returns the path of the PKCS#8 private key file used by the TLS + * socket. + * + * \return The path of the PKCS#8 private key file used by the TLS socket + */ +- (OFString*)privateKeyFile; + +/** + * \brief Sets the passphrase to decrypt the PKCS#8 private key file. + * + * \warning You have to ensure that this is in secure memory that is protected + * from swapping! This is also the reason why this is not an OFString. + * + * \param privateKeyPassphrase The passphrase to decrypt the PKCS#8 private + * key file + */ +- (void)setPrivateKeyPassphrase: (const char*)privateKeyPassphrase; + +/** + * \brief Returns the passphrase to decrypt the PKCS#8 private key file. + * + * \warning You should not copy this to insecure memory that is swappable! + * + * \return The passphrase to decrypt the PKCS#8 private key file + */ +- (const char*)privateKeyPassphrase; +@end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -44,10 +44,11 @@ #import "OFStream.h" #import "OFFile.h" #import "OFStreamSocket.h" #import "OFTCPSocket.h" +#import "OFTLSSocket.h" #import "OFProcess.h" #import "OFStreamObserver.h" #import "OFHTTPRequest.h"