Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -93,10 +93,16 @@ 4B0EA925189869D900F573A4 /* OFUDPSocketTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0EA924189869D900F573A4 /* OFUDPSocketTests.m */; }; 4B11005C14329B9A003A45D8 /* OFXMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B11005A14329B9A003A45D8 /* OFXMLNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B11005D14329B9A003A45D8 /* OFXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B11005B14329B9A003A45D8 /* OFXMLNode.m */; }; 4B11D09C1EC901440094423D /* OFHTTPCookieManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B11D09B1EC901440094423D /* OFHTTPCookieManagerTests.m */; }; 4B11D09D1EC901440094423D /* OFHTTPCookieManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B11D09B1EC901440094423D /* OFHTTPCookieManagerTests.m */; }; + 4B1223141F23E6C000D9F8FF /* OFData+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1223101F23E6B300D9F8FF /* OFData+Private.h */; }; + 4B1223151F23E6C000D9F8FF /* OFMutableData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1223111F23E6B300D9F8FF /* OFMutableData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B1223161F23E6C000D9F8FF /* OFMutableData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1223121F23E6B300D9F8FF /* OFMutableData.m */; }; + 4B1223171F23E6C100D9F8FF /* OFData+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1223101F23E6B300D9F8FF /* OFData+Private.h */; }; + 4B1223181F23E6C100D9F8FF /* OFMutableData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1223111F23E6B300D9F8FF /* OFMutableData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B1223191F23E6C100D9F8FF /* OFMutableData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1223121F23E6B300D9F8FF /* OFMutableData.m */; }; 4B141BA415FCDF74000C21A8 /* OFSortedList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B141BA215FCDF74000C21A8 /* OFSortedList.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B141BA515FCDF74000C21A8 /* OFSortedList.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B141BA315FCDF74000C21A8 /* OFSortedList.m */; }; 4B1473CB17E6391900B46BB8 /* OFAutoreleasePool+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */; }; 4B14EAC71E9A8292005E8BFD /* OFSandboxActivationFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B14EAC81E9A8292005E8BFD /* OFSandboxActivationFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -206,19 +212,18 @@ 4B2C21201DA292BE00735907 /* OFArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B67995B1099E7C50041064A /* OFArray.m */; }; 4B2C21211DA292BE00735907 /* OFArray_adjacent.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E74140D430500EC2F7C /* OFArray_adjacent.m */; }; 4B2C21221DA292BE00735907 /* OFArray_adjacentSubarray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BB7BA141CDE2D000AD1CC /* OFArray_adjacentSubarray.m */; }; 4B2C21231DA292BE00735907 /* OFArray_subarray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BB7BC141CDE2D000AD1CC /* OFArray_subarray.m */; }; 4B2C21241DA292BE00735907 /* OFAutoreleasePool.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */; }; - 4B2C21251DA292BE00735907 /* OFBigDataArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF48CE018A95F83000E8D04 /* OFBigDataArray.m */; }; 4B2C21261DA292BE00735907 /* OFBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD86D811237A6C600ED9912 /* OFBlock.m */; }; 4B2C21271DA292BE00735907 /* OFCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6743F8163C395900EB1E59 /* OFCondition.m */; }; 4B2C21281DA292BE00735907 /* OFConstantString.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0D812DF4225005C7A0C /* OFConstantString.m */; }; 4B2C21291DA292BE00735907 /* OFCountedSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B45355213DCFE1E0037AB4D /* OFCountedSet.m */; }; 4B2C212A1DA292BE00735907 /* OFCountedSet_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA85BC5140ECCE800E91D51 /* OFCountedSet_hashtable.m */; }; - 4B2C212B1DA292BE00735907 /* OFDataArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799611099E7C50041064A /* OFDataArray.m */; }; - 4B2C212C1DA292BE00735907 /* OFDataArray+CryptoHashing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE17ADA12FD746D002CEB0B /* OFDataArray+CryptoHashing.m */; }; - 4B2C212D1DA292BE00735907 /* OFDataArray+MessagePackValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B879A8A177231F000EBCEA4 /* OFDataArray+MessagePackValue.m */; }; + 4B2C212B1DA292BE00735907 /* OFData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799611099E7C50041064A /* OFData.m */; }; + 4B2C212C1DA292BE00735907 /* OFData+CryptoHashing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE17ADA12FD746D002CEB0B /* OFData+CryptoHashing.m */; }; + 4B2C212D1DA292BE00735907 /* OFData+MessagePackValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B879A8A177231F000EBCEA4 /* OFData+MessagePackValue.m */; }; 4B2C212E1DA292BE00735907 /* OFDate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0DA12DF4225005C7A0C /* OFDate.m */; }; 4B2C21311DA292BE00735907 /* OFDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799631099E7C50041064A /* OFDictionary.m */; }; 4B2C21321DA292BE00735907 /* OFDictionary_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E76140D430500EC2F7C /* OFDictionary_hashtable.m */; }; 4B2C21331DA292BE00735907 /* OFEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0108CA10EB8C9300631877 /* OFEnumerator.m */; }; 4B2C21341DA292BE00735907 /* OFFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799671099E7C50041064A /* OFFile.m */; }; @@ -381,20 +386,19 @@ 4B2C21D41DA292BE00735907 /* forwarding.S in Sources */ = {isa = PBXBuildFile; fileRef = 4B5C112C17E9AAED003C917F /* forwarding.S */; }; 4B2C21D71DA292BE00735907 /* OFApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B175C1D116D130B003C99CB /* OFApplication.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21D81DA292BE00735907 /* OFArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B67995A1099E7C50041064A /* OFArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21D91DA292BE00735907 /* OFArray_subarray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9BB7BB141CDE2D000AD1CC /* OFArray_subarray.h */; }; 4B2C21DA1DA292BE00735907 /* OFAutoreleasePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B2C21DB1DA292BE00735907 /* OFBigDataArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF48CDF18A95F83000E8D04 /* OFBigDataArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21DC1DA292BE00735907 /* OFBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD86D801237A6C600ED9912 /* OFBlock.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21DD1DA292BE00735907 /* OFCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAF5F46123460C900F4E111 /* OFCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21DE1DA292BE00735907 /* OFCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6743F7163C395900EB1E59 /* OFCondition.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21DF1DA292BE00735907 /* OFConstantString.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5F0D712DF4225005C7A0C /* OFConstantString.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21E01DA292BE00735907 /* OFCountedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B45355113DCFE1E0037AB4D /* OFCountedSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21E11DA292BE00735907 /* OFCryptoHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF1BCC011C9663F0025511F /* OFCryptoHash.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B2C21E21DA292BE00735907 /* OFDataArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799601099E7C50041064A /* OFDataArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B2C21E31DA292BE00735907 /* OFDataArray+CryptoHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE17AD912FD746D002CEB0B /* OFDataArray+CryptoHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B2C21E41DA292BE00735907 /* OFDataArray+MessagePackValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A89177231F000EBCEA4 /* OFDataArray+MessagePackValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B2C21E21DA292BE00735907 /* OFData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799601099E7C50041064A /* OFData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B2C21E31DA292BE00735907 /* OFData+CryptoHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE17AD912FD746D002CEB0B /* OFData+CryptoHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B2C21E41DA292BE00735907 /* OFData+MessagePackValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A89177231F000EBCEA4 /* OFData+MessagePackValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21E51DA292BE00735907 /* OFDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5F0D912DF4225005C7A0C /* OFDate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21E81DA292BE00735907 /* OFDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799621099E7C50041064A /* OFDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21E91DA292BE00735907 /* OFEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B0108C910EB8C9300631877 /* OFEnumerator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21EA1DA292BE00735907 /* OFException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF70133A28FC003E6DCD /* OFException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2C21EB1DA292BE00735907 /* OFFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799661099E7C50041064A /* OFFile.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -607,12 +611,12 @@ 4B3D238B1337FC0D00DD29B8 /* OFApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B175C1E116D130B003C99CB /* OFApplication.m */; }; 4B3D238C1337FC0D00DD29B8 /* OFArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B67995B1099E7C50041064A /* OFArray.m */; }; 4B3D238D1337FC0D00DD29B8 /* OFAutoreleasePool.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */; }; 4B3D238E1337FC0D00DD29B8 /* OFBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD86D811237A6C600ED9912 /* OFBlock.m */; }; 4B3D238F1337FC0D00DD29B8 /* OFConstantString.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0D812DF4225005C7A0C /* OFConstantString.m */; }; - 4B3D23901337FC0D00DD29B8 /* OFDataArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799611099E7C50041064A /* OFDataArray.m */; }; - 4B3D23911337FC0D00DD29B8 /* OFDataArray+CryptoHashing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE17ADA12FD746D002CEB0B /* OFDataArray+CryptoHashing.m */; }; + 4B3D23901337FC0D00DD29B8 /* OFData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799611099E7C50041064A /* OFData.m */; }; + 4B3D23911337FC0D00DD29B8 /* OFData+CryptoHashing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE17ADA12FD746D002CEB0B /* OFData+CryptoHashing.m */; }; 4B3D23921337FC0D00DD29B8 /* OFDate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0DA12DF4225005C7A0C /* OFDate.m */; }; 4B3D23931337FC0D00DD29B8 /* OFDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799631099E7C50041064A /* OFDictionary.m */; }; 4B3D23941337FC0D00DD29B8 /* OFEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0108CA10EB8C9300631877 /* OFEnumerator.m */; }; 4B3D23961337FC0D00DD29B8 /* OFFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6799671099E7C50041064A /* OFFile.m */; }; 4B3D23981337FC0D00DD29B8 /* OFHTTPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B99251012E0780000215DBE /* OFHTTPRequest.m */; }; @@ -649,12 +653,12 @@ 4B3D23BD1337FC8300DD29B8 /* OFArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B67995A1099E7C50041064A /* OFArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23BE1337FC8300DD29B8 /* OFAutoreleasePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23BF1337FC8300DD29B8 /* OFBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD86D801237A6C600ED9912 /* OFBlock.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C01337FC8300DD29B8 /* OFCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAF5F46123460C900F4E111 /* OFCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C11337FC8300DD29B8 /* OFConstantString.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5F0D712DF4225005C7A0C /* OFConstantString.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B3D23C21337FC8300DD29B8 /* OFDataArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799601099E7C50041064A /* OFDataArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B3D23C31337FC8300DD29B8 /* OFDataArray+CryptoHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE17AD912FD746D002CEB0B /* OFDataArray+CryptoHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3D23C21337FC8300DD29B8 /* OFData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799601099E7C50041064A /* OFData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3D23C31337FC8300DD29B8 /* OFData+CryptoHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE17AD912FD746D002CEB0B /* OFData+CryptoHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C41337FC8300DD29B8 /* OFDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5F0D912DF4225005C7A0C /* OFDate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C51337FCB000DD29B8 /* OFDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799621099E7C50041064A /* OFDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C61337FCB000DD29B8 /* OFEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B0108C910EB8C9300631877 /* OFEnumerator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C81337FCB000DD29B8 /* OFFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6799661099E7C50041064A /* OFFile.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23C91337FCB000DD29B8 /* OFCryptoHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF1BCC011C9663F0025511F /* OFCryptoHash.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -820,12 +824,12 @@ 4B8385171951BF9500D5358A /* OFSettings_INIFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8385131951BF9500D5358A /* OFSettings_INIFile.m */; }; 4B8385181951BF9500D5358A /* OFSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8385141951BF9500D5358A /* OFSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B8385191951BF9500D5358A /* OFSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8385151951BF9500D5358A /* OFSettings.m */; }; 4B853CEB1EBFDEB000A4B2C4 /* OFXMLNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B853CEA1EBFDEB000A4B2C4 /* OFXMLNode+Private.h */; }; 4B853CEC1EBFDEB000A4B2C4 /* OFXMLNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B853CEA1EBFDEB000A4B2C4 /* OFXMLNode+Private.h */; }; - 4B879A8C177231F000EBCEA4 /* OFDataArray+MessagePackValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A89177231F000EBCEA4 /* OFDataArray+MessagePackValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B879A8D177231F000EBCEA4 /* OFDataArray+MessagePackValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B879A8A177231F000EBCEA4 /* OFDataArray+MessagePackValue.m */; }; + 4B879A8C177231F000EBCEA4 /* OFData+MessagePackValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A89177231F000EBCEA4 /* OFData+MessagePackValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B879A8D177231F000EBCEA4 /* OFData+MessagePackValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B879A8A177231F000EBCEA4 /* OFData+MessagePackValue.m */; }; 4B879A8E177231F000EBCEA4 /* OFMessagePackRepresentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A8B177231F000EBCEA4 /* OFMessagePackRepresentation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B881D3C1CCBFE2600E2F7D8 /* crc32.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B881D391CCBFE0700E2F7D8 /* crc32.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B881D3D1CCBFE2A00E2F7D8 /* crc32.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B881D3A1CCBFE0700E2F7D8 /* crc32.m */; }; 4B8B025917BBA7C7009ED983 /* OFZIPArchiveEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8B025717BBA7C7009ED983 /* OFZIPArchiveEntry.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B8B025A17BBA7C7009ED983 /* OFZIPArchiveEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8B025817BBA7C7009ED983 /* OFZIPArchiveEntry.m */; }; @@ -925,11 +929,11 @@ 4BD98C03133814220048DD5B /* objfw-defs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD98C011338140B0048DD5B /* objfw-defs.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BD9C9FF1DA2C5B800E5AD52 /* ObjFW.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B2C22B01DA292BE00735907 /* ObjFW.framework */; }; 4BD9CA001DA2C5FC00E5AD52 /* ForwardingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA4846515CC9FAD00D75360 /* ForwardingTests.m */; }; 4BD9CA011DA2C5FE00E5AD52 /* OFArrayTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF66E1235358D0076B512 /* OFArrayTests.m */; }; 4BD9CA021DA2C60200E5AD52 /* OFBlockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0E412DF4259005C7A0C /* OFBlockTests.m */; }; - 4BD9CA031DA2C60400E5AD52 /* OFDataArrayTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF66F1235358D0076B512 /* OFDataArrayTests.m */; }; + 4BD9CA031DA2C60400E5AD52 /* OFDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF66F1235358D0076B512 /* OFDataTests.m */; }; 4BD9CA041DA2C60700E5AD52 /* OFDateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0E512DF4259005C7A0C /* OFDateTests.m */; }; 4BD9CA051DA2C60900E5AD52 /* OFDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF6701235358D0076B512 /* OFDictionaryTests.m */; }; 4BD9CA061DA2C60B00E5AD52 /* OFHMACTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0DD731D44645D001D9949 /* OFHMACTests.m */; }; 4BD9CA071DA2C60E00E5AD52 /* OFHTTPClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4B54916776094002A2DCE /* OFHTTPClientTests.m */; }; 4BD9CA081DA2C61900E5AD52 /* OFHTTPCookieTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2610C51D86305C001F16C9 /* OFHTTPCookieTests.m */; }; @@ -985,11 +989,11 @@ 4BF20C571EEBF5F000C53220 /* OFInflateStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF20C501EEBF5F000C53220 /* OFInflateStream.m */; }; 4BF20C581EEBF5F000C53220 /* OFInflateStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF20C501EEBF5F000C53220 /* OFInflateStream.m */; }; 4BF33AFB133807590059CEF7 /* ObjFW.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B3D23761337FBC800DD29B8 /* ObjFW.framework */; }; 4BF33AFC133807A20059CEF7 /* OFArrayTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF66E1235358D0076B512 /* OFArrayTests.m */; }; 4BF33AFD133807A20059CEF7 /* OFBlockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0E412DF4259005C7A0C /* OFBlockTests.m */; }; - 4BF33AFE133807A20059CEF7 /* OFDataArrayTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF66F1235358D0076B512 /* OFDataArrayTests.m */; }; + 4BF33AFE133807A20059CEF7 /* OFDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF66F1235358D0076B512 /* OFDataTests.m */; }; 4BF33AFF133807A20059CEF7 /* OFDateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5F0E512DF4259005C7A0C /* OFDateTests.m */; }; 4BF33B00133807A20059CEF7 /* OFDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF6701235358D0076B512 /* OFDictionaryTests.m */; }; 4BF33B03133807A20059CEF7 /* OFListTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF6721235358D0076B512 /* OFListTests.m */; }; 4BF33B04133807A20059CEF7 /* OFMD5HashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF6731235358D0076B512 /* OFMD5HashTests.m */; }; 4BF33B05133807A20059CEF7 /* OFNumberTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF6741235358D0076B512 /* OFNumberTests.m */; }; @@ -1006,12 +1010,10 @@ 4BF33B12133807A20059CEF7 /* TestsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EF6811235358D0076B512 /* TestsAppDelegate.m */; }; 4BF33B4713380CE20059CEF7 /* testfile.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BF33B4313380CD40059CEF7 /* testfile.txt */; }; 4BF33B4813380D2D0059CEF7 /* testfile.bin in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BF33B4213380CD40059CEF7 /* testfile.bin */; }; 4BF3A2291E25EA48002EA46F /* windows_1251.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3A2281E25EA48002EA46F /* windows_1251.m */; }; 4BF3A22A1E25EA48002EA46F /* windows_1251.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3A2281E25EA48002EA46F /* windows_1251.m */; }; - 4BF48CE118A95F83000E8D04 /* OFBigDataArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF48CDF18A95F83000E8D04 /* OFBigDataArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4BF48CE218A95F83000E8D04 /* OFBigDataArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF48CE018A95F83000E8D04 /* OFBigDataArray.m */; }; 4BF5CB901E2DC1D800CF7584 /* iso_8859_2.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5CB8F1E2DC1D800CF7584 /* iso_8859_2.m */; }; 4BF5CB911E2DC1D800CF7584 /* iso_8859_2.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5CB8F1E2DC1D800CF7584 /* iso_8859_2.m */; }; 4BF69CE61BD44F8B00DFFC1B /* platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF69CE51BD44F8B00DFFC1B /* platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BFC37BD1E50E11C00EE1269 /* common.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFC37BC1E50E11C00EE1269 /* common.h */; }; 4BFC37BE1E50E11C00EE1269 /* common.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFC37BC1E50E11C00EE1269 /* common.h */; }; @@ -1186,10 +1188,13 @@ 4B0EA91A1898690E00F573A4 /* OFKernelEventObserver+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFKernelEventObserver+Private.h"; path = "src/OFKernelEventObserver+Private.h"; sourceTree = ""; }; 4B0EA924189869D900F573A4 /* OFUDPSocketTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFUDPSocketTests.m; path = tests/OFUDPSocketTests.m; sourceTree = ""; }; 4B11005A14329B9A003A45D8 /* OFXMLNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFXMLNode.h; path = src/OFXMLNode.h; sourceTree = ""; }; 4B11005B14329B9A003A45D8 /* OFXMLNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLNode.m; path = src/OFXMLNode.m; sourceTree = ""; }; 4B11D09B1EC901440094423D /* OFHTTPCookieManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFHTTPCookieManagerTests.m; path = tests/OFHTTPCookieManagerTests.m; sourceTree = ""; }; + 4B1223101F23E6B300D9F8FF /* OFData+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFData+Private.h"; path = "src/OFData+Private.h"; sourceTree = ""; }; + 4B1223111F23E6B300D9F8FF /* OFMutableData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableData.h; path = src/OFMutableData.h; sourceTree = ""; }; + 4B1223121F23E6B300D9F8FF /* OFMutableData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableData.m; path = src/OFMutableData.m; sourceTree = ""; }; 4B141BA215FCDF74000C21A8 /* OFSortedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSortedList.h; path = src/OFSortedList.h; sourceTree = ""; }; 4B141BA315FCDF74000C21A8 /* OFSortedList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSortedList.m; path = src/OFSortedList.m; sourceTree = ""; }; 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFAutoreleasePool+Private.h"; path = "src/OFAutoreleasePool+Private.h"; sourceTree = ""; }; 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSandboxActivationFailedException.h; path = src/exceptions/OFSandboxActivationFailedException.h; sourceTree = ""; }; 4B14EAC61E9A8292005E8BFD /* OFSandboxActivationFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSandboxActivationFailedException.m; path = src/exceptions/OFSandboxActivationFailedException.m; sourceTree = ""; }; @@ -1406,12 +1411,12 @@ 4B6743FD163C395900EB1E59 /* OFRecursiveMutex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFRecursiveMutex.m; path = src/OFRecursiveMutex.m; sourceTree = ""; }; 4B67995A1099E7C50041064A /* OFArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFArray.h; path = src/OFArray.h; sourceTree = ""; }; 4B67995B1099E7C50041064A /* OFArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFArray.m; path = src/OFArray.m; sourceTree = ""; }; 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFAutoreleasePool.h; path = src/OFAutoreleasePool.h; sourceTree = ""; }; 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFAutoreleasePool.m; path = src/OFAutoreleasePool.m; sourceTree = ""; }; - 4B6799601099E7C50041064A /* OFDataArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDataArray.h; path = src/OFDataArray.h; sourceTree = ""; }; - 4B6799611099E7C50041064A /* OFDataArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDataArray.m; path = src/OFDataArray.m; sourceTree = ""; }; + 4B6799601099E7C50041064A /* OFData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFData.h; path = src/OFData.h; sourceTree = ""; }; + 4B6799611099E7C50041064A /* OFData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFData.m; path = src/OFData.m; sourceTree = ""; }; 4B6799621099E7C50041064A /* OFDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDictionary.h; path = src/OFDictionary.h; sourceTree = ""; }; 4B6799631099E7C50041064A /* OFDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDictionary.m; path = src/OFDictionary.m; sourceTree = ""; }; 4B6799661099E7C50041064A /* OFFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFFile.h; path = src/OFFile.h; sourceTree = ""; }; 4B6799671099E7C50041064A /* OFFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFFile.m; path = src/OFFile.m; sourceTree = ""; }; 4B67996C1099E7C50041064A /* OFList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFList.h; path = src/OFList.h; sourceTree = ""; }; @@ -1454,11 +1459,11 @@ 4B6C8AD617BD5C2E00B194F2 /* OFTimer+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFTimer+Private.h"; path = "src/OFTimer+Private.h"; sourceTree = ""; }; 4B6C8AD717BD5C2E00B194F2 /* OFZIPArchiveEntry+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFZIPArchiveEntry+Private.h"; path = "src/OFZIPArchiveEntry+Private.h"; sourceTree = ""; }; 4B6D0A871D4459D900901D8D /* OFHMAC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFHMAC.h; path = src/OFHMAC.h; sourceTree = ""; }; 4B6D0A881D4459D900901D8D /* OFHMAC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFHMAC.m; path = src/OFHMAC.m; sourceTree = ""; }; 4B6EF66E1235358D0076B512 /* OFArrayTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFArrayTests.m; path = tests/OFArrayTests.m; sourceTree = SOURCE_ROOT; }; - 4B6EF66F1235358D0076B512 /* OFDataArrayTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDataArrayTests.m; path = tests/OFDataArrayTests.m; sourceTree = SOURCE_ROOT; }; + 4B6EF66F1235358D0076B512 /* OFDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDataTests.m; path = tests/OFDataTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6701235358D0076B512 /* OFDictionaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDictionaryTests.m; path = tests/OFDictionaryTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6721235358D0076B512 /* OFListTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFListTests.m; path = tests/OFListTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6731235358D0076B512 /* OFMD5HashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMD5HashTests.m; path = tests/OFMD5HashTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6741235358D0076B512 /* OFNumberTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFNumberTests.m; path = tests/OFNumberTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6751235358D0076B512 /* OFObjectTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFObjectTests.m; path = tests/OFObjectTests.m; sourceTree = SOURCE_ROOT; }; @@ -1498,12 +1503,12 @@ 4B8385121951BF9500D5358A /* OFSettings_INIFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSettings_INIFile.h; path = src/OFSettings_INIFile.h; sourceTree = ""; }; 4B8385131951BF9500D5358A /* OFSettings_INIFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSettings_INIFile.m; path = src/OFSettings_INIFile.m; sourceTree = ""; }; 4B8385141951BF9500D5358A /* OFSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSettings.h; path = src/OFSettings.h; sourceTree = ""; }; 4B8385151951BF9500D5358A /* OFSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSettings.m; path = src/OFSettings.m; sourceTree = ""; }; 4B853CEA1EBFDEB000A4B2C4 /* OFXMLNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFXMLNode+Private.h"; path = "src/OFXMLNode+Private.h"; sourceTree = ""; }; - 4B879A89177231F000EBCEA4 /* OFDataArray+MessagePackValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFDataArray+MessagePackValue.h"; path = "src/OFDataArray+MessagePackValue.h"; sourceTree = ""; }; - 4B879A8A177231F000EBCEA4 /* OFDataArray+MessagePackValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFDataArray+MessagePackValue.m"; path = "src/OFDataArray+MessagePackValue.m"; sourceTree = ""; }; + 4B879A89177231F000EBCEA4 /* OFData+MessagePackValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFData+MessagePackValue.h"; path = "src/OFData+MessagePackValue.h"; sourceTree = ""; }; + 4B879A8A177231F000EBCEA4 /* OFData+MessagePackValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFData+MessagePackValue.m"; path = "src/OFData+MessagePackValue.m"; sourceTree = ""; }; 4B879A8B177231F000EBCEA4 /* OFMessagePackRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMessagePackRepresentation.h; path = src/OFMessagePackRepresentation.h; sourceTree = ""; }; 4B881D391CCBFE0700E2F7D8 /* crc32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = src/crc32.h; sourceTree = ""; }; 4B881D3A1CCBFE0700E2F7D8 /* crc32.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = crc32.m; path = src/crc32.m; sourceTree = ""; }; 4B8B025717BBA7C7009ED983 /* OFZIPArchiveEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFZIPArchiveEntry.h; path = src/OFZIPArchiveEntry.h; sourceTree = ""; }; 4B8B025817BBA7C7009ED983 /* OFZIPArchiveEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFZIPArchiveEntry.m; path = src/OFZIPArchiveEntry.m; sourceTree = ""; }; @@ -1614,12 +1619,12 @@ 4BD86D801237A6C600ED9912 /* OFBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFBlock.h; path = src/OFBlock.h; sourceTree = SOURCE_ROOT; }; 4BD86D811237A6C600ED9912 /* OFBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFBlock.m; path = src/OFBlock.m; sourceTree = SOURCE_ROOT; }; 4BD98C011338140B0048DD5B /* objfw-defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "objfw-defs.h"; path = "src/objfw-defs.h"; sourceTree = SOURCE_ROOT; }; 4BDF37B41338055600F9A81A /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; }; 4BE17AD812FD744C002CEB0B /* foundation-compat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "foundation-compat.m"; path = "src/foundation-compat.m"; sourceTree = SOURCE_ROOT; }; - 4BE17AD912FD746D002CEB0B /* OFDataArray+CryptoHashing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFDataArray+CryptoHashing.h"; path = "src/OFDataArray+CryptoHashing.h"; sourceTree = SOURCE_ROOT; }; - 4BE17ADA12FD746D002CEB0B /* OFDataArray+CryptoHashing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFDataArray+CryptoHashing.m"; path = "src/OFDataArray+CryptoHashing.m"; sourceTree = SOURCE_ROOT; }; + 4BE17AD912FD746D002CEB0B /* OFData+CryptoHashing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFData+CryptoHashing.h"; path = "src/OFData+CryptoHashing.h"; sourceTree = SOURCE_ROOT; }; + 4BE17ADA12FD746D002CEB0B /* OFData+CryptoHashing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFData+CryptoHashing.m"; path = "src/OFData+CryptoHashing.m"; sourceTree = SOURCE_ROOT; }; 4BE52D1F17B990B4005958D1 /* OFZIPArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFZIPArchive.h; path = src/OFZIPArchive.h; sourceTree = ""; }; 4BE52D2017B990B4005958D1 /* OFZIPArchive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFZIPArchive.m; path = src/OFZIPArchive.m; sourceTree = ""; }; 4BE52D2317B990DA005958D1 /* OFChecksumFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFChecksumFailedException.h; path = src/exceptions/OFChecksumFailedException.h; sourceTree = ""; }; 4BE52D2417B990DA005958D1 /* OFChecksumFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFChecksumFailedException.m; path = src/exceptions/OFChecksumFailedException.m; sourceTree = ""; }; 4BE5F0D712DF4225005C7A0C /* OFConstantString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFConstantString.h; path = src/OFConstantString.h; sourceTree = SOURCE_ROOT; }; @@ -1657,12 +1662,10 @@ 4BF20C501EEBF5F000C53220 /* OFInflateStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFInflateStream.m; path = src/OFInflateStream.m; sourceTree = ""; }; 4BF33AF0133807310059CEF7 /* Tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Tests; sourceTree = BUILT_PRODUCTS_DIR; }; 4BF33B4213380CD40059CEF7 /* testfile.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = testfile.bin; path = tests/testfile.bin; sourceTree = ""; }; 4BF33B4313380CD40059CEF7 /* testfile.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = testfile.txt; path = tests/testfile.txt; sourceTree = ""; }; 4BF3A2281E25EA48002EA46F /* windows_1251.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = windows_1251.m; path = src/encodings/windows_1251.m; sourceTree = ""; }; - 4BF48CDF18A95F83000E8D04 /* OFBigDataArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFBigDataArray.h; path = src/OFBigDataArray.h; sourceTree = ""; }; - 4BF48CE018A95F83000E8D04 /* OFBigDataArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFBigDataArray.m; path = src/OFBigDataArray.m; sourceTree = ""; }; 4BF5CB8F1E2DC1D800CF7584 /* iso_8859_2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iso_8859_2.m; path = src/encodings/iso_8859_2.m; sourceTree = ""; }; 4BF69CE51BD44F8B00DFFC1B /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform.h; path = src/platform.h; sourceTree = ""; }; 4BFBDD1610A0724800051AFB /* unicode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = unicode.m; path = src/unicode.m; sourceTree = ""; }; 4BFC37BC1E50E11C00EE1269 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = src/encodings/common.h; sourceTree = ""; }; 4BFF3710177E17C100192782 /* OFRemoveItemFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFRemoveItemFailedException.h; path = src/exceptions/OFRemoveItemFailedException.h; sourceTree = ""; }; @@ -2010,12 +2013,10 @@ 4B9BB7BB141CDE2D000AD1CC /* OFArray_subarray.h */, 4B9BB7BC141CDE2D000AD1CC /* OFArray_subarray.m */, 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */, 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */, 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */, - 4BF48CDF18A95F83000E8D04 /* OFBigDataArray.h */, - 4BF48CE018A95F83000E8D04 /* OFBigDataArray.m */, 4BD86D801237A6C600ED9912 /* OFBlock.h */, 4BD86D811237A6C600ED9912 /* OFBlock.m */, 4BAF5F46123460C900F4E111 /* OFCollection.h */, 4B6743F7163C395900EB1E59 /* OFCondition.h */, 4B6743F8163C395900EB1E59 /* OFCondition.m */, @@ -2024,16 +2025,17 @@ 4B45355113DCFE1E0037AB4D /* OFCountedSet.h */, 4B45355213DCFE1E0037AB4D /* OFCountedSet.m */, 4BA85BC4140ECCE800E91D51 /* OFCountedSet_hashtable.h */, 4BA85BC5140ECCE800E91D51 /* OFCountedSet_hashtable.m */, 4BF1BCC011C9663F0025511F /* OFCryptoHash.h */, - 4B6799601099E7C50041064A /* OFDataArray.h */, - 4B6799611099E7C50041064A /* OFDataArray.m */, - 4BE17AD912FD746D002CEB0B /* OFDataArray+CryptoHashing.h */, - 4BE17ADA12FD746D002CEB0B /* OFDataArray+CryptoHashing.m */, - 4B879A89177231F000EBCEA4 /* OFDataArray+MessagePackValue.h */, - 4B879A8A177231F000EBCEA4 /* OFDataArray+MessagePackValue.m */, + 4B6799601099E7C50041064A /* OFData.h */, + 4B6799611099E7C50041064A /* OFData.m */, + 4BE17AD912FD746D002CEB0B /* OFData+CryptoHashing.h */, + 4BE17ADA12FD746D002CEB0B /* OFData+CryptoHashing.m */, + 4B879A89177231F000EBCEA4 /* OFData+MessagePackValue.h */, + 4B879A8A177231F000EBCEA4 /* OFData+MessagePackValue.m */, + 4B1223101F23E6B300D9F8FF /* OFData+Private.h */, 4BE5F0D912DF4225005C7A0C /* OFDate.h */, 4BE5F0DA12DF4225005C7A0C /* OFDate.m */, 4B6799621099E7C50041064A /* OFDictionary.h */, 4B6799631099E7C50041064A /* OFDictionary.m */, 4B2B3E75140D430500EC2F7C /* OFDictionary_hashtable.h */, @@ -2097,10 +2099,12 @@ 4B879A8B177231F000EBCEA4 /* OFMessagePackRepresentation.h */, 4B67996F1099E7C50041064A /* OFMutableArray.h */, 4B6799701099E7C50041064A /* OFMutableArray.m */, 4B2B3E77140D430500EC2F7C /* OFMutableArray_adjacent.h */, 4B2B3E78140D430500EC2F7C /* OFMutableArray_adjacent.m */, + 4B1223111F23E6B300D9F8FF /* OFMutableData.h */, + 4B1223121F23E6B300D9F8FF /* OFMutableData.m */, 4B6799711099E7C50041064A /* OFMutableDictionary.h */, 4B6799721099E7C50041064A /* OFMutableDictionary.m */, 4B2B3E79140D430500EC2F7C /* OFMutableDictionary_hashtable.h */, 4B2B3E7A140D430500EC2F7C /* OFMutableDictionary_hashtable.m */, 4B39844513D3AFB400E6F825 /* OFMutableSet.h */, @@ -2292,11 +2296,11 @@ 4BF33B4113380CB60059CEF7 /* Supporting Files */, 4B6EF682123535960076B512 /* objc_sync */, 4BA4846515CC9FAD00D75360 /* ForwardingTests.m */, 4B6EF66E1235358D0076B512 /* OFArrayTests.m */, 4BE5F0E412DF4259005C7A0C /* OFBlockTests.m */, - 4B6EF66F1235358D0076B512 /* OFDataArrayTests.m */, + 4B6EF66F1235358D0076B512 /* OFDataTests.m */, 4BE5F0E512DF4259005C7A0C /* OFDateTests.m */, 4B6EF6701235358D0076B512 /* OFDictionaryTests.m */, 4BF0DD731D44645D001D9949 /* OFHMACTests.m */, 4BB4B54916776094002A2DCE /* OFHTTPClientTests.m */, 4B2610C51D86305C001F16C9 /* OFHTTPCookieTests.m */, @@ -2429,20 +2433,19 @@ buildActionMask = 2147483647; files = ( 4B2C21D71DA292BE00735907 /* OFApplication.h in Headers */, 4B2C21D81DA292BE00735907 /* OFArray.h in Headers */, 4B2C21DA1DA292BE00735907 /* OFAutoreleasePool.h in Headers */, - 4B2C21DB1DA292BE00735907 /* OFBigDataArray.h in Headers */, 4B2C21DC1DA292BE00735907 /* OFBlock.h in Headers */, 4B2C21DD1DA292BE00735907 /* OFCollection.h in Headers */, 4B2C21DE1DA292BE00735907 /* OFCondition.h in Headers */, 4B2C21DF1DA292BE00735907 /* OFConstantString.h in Headers */, 4B2C21E01DA292BE00735907 /* OFCountedSet.h in Headers */, 4B2C21E11DA292BE00735907 /* OFCryptoHash.h in Headers */, - 4B2C21E21DA292BE00735907 /* OFDataArray.h in Headers */, - 4B2C21E31DA292BE00735907 /* OFDataArray+CryptoHashing.h in Headers */, - 4B2C21E41DA292BE00735907 /* OFDataArray+MessagePackValue.h in Headers */, + 4B2C21E21DA292BE00735907 /* OFData.h in Headers */, + 4B2C21E31DA292BE00735907 /* OFData+CryptoHashing.h in Headers */, + 4B2C21E41DA292BE00735907 /* OFData+MessagePackValue.h in Headers */, 4B2C21E51DA292BE00735907 /* OFDate.h in Headers */, 4B2C21E81DA292BE00735907 /* OFDictionary.h in Headers */, 4B2C21E91DA292BE00735907 /* OFEnumerator.h in Headers */, 4B2C21EA1DA292BE00735907 /* OFException.h in Headers */, 4B2C21EB1DA292BE00735907 /* OFFile.h in Headers */, @@ -2469,10 +2472,11 @@ 4B2C21FC1DA292BE00735907 /* OFMapTable.h in Headers */, 4B2C21FD1DA292BE00735907 /* OFMD5Hash.h in Headers */, 4B2C21FE1DA292BE00735907 /* OFMessagePackExtension.h in Headers */, 4B2C21FF1DA292BE00735907 /* OFMessagePackRepresentation.h in Headers */, 4B2C22001DA292BE00735907 /* OFMutableArray.h in Headers */, + 4B1223181F23E6C100D9F8FF /* OFMutableData.h in Headers */, 4B2C22011DA292BE00735907 /* OFMutableDictionary.h in Headers */, 4B2C22021DA292BE00735907 /* OFMutableSet.h in Headers */, 4B2C22031DA292BE00735907 /* OFMutableString.h in Headers */, 4B4116D11F21654200E78916 /* OFMutableURL.h in Headers */, 4B2C22041DA292BE00735907 /* OFMutex.h in Headers */, @@ -2617,10 +2621,11 @@ 4B2C228E1DA292BE00735907 /* OFArray_adjacent.h in Headers */, 4B2C228F1DA292BE00735907 /* OFArray_adjacentSubarray.h in Headers */, 4B2C21D91DA292BE00735907 /* OFArray_subarray.h in Headers */, 4B2C22901DA292BE00735907 /* OFAutoreleasePool+Private.h in Headers */, 4B2C22911DA292BE00735907 /* OFCountedSet_hashtable.h in Headers */, + 4B1223171F23E6C100D9F8FF /* OFData+Private.h in Headers */, 4B2C22921DA292BE00735907 /* OFDictionary_hashtable.h in Headers */, 4B2C22931DA292BE00735907 /* OFINICategory+Private.h in Headers */, 4B2C22941DA292BE00735907 /* OFKernelEventObserver+Private.h in Headers */, 4B2C22951DA292BE00735907 /* OFKernelEventObserver_kqueue.h in Headers */, 4B2C22961DA292BE00735907 /* OFKernelEventObserver_poll.h in Headers */, @@ -2655,20 +2660,19 @@ buildActionMask = 2147483647; files = ( 4B3D23BC1337FC8300DD29B8 /* OFApplication.h in Headers */, 4B3D23BD1337FC8300DD29B8 /* OFArray.h in Headers */, 4B3D23BE1337FC8300DD29B8 /* OFAutoreleasePool.h in Headers */, - 4BF48CE118A95F83000E8D04 /* OFBigDataArray.h in Headers */, 4B3D23BF1337FC8300DD29B8 /* OFBlock.h in Headers */, 4B3D23C01337FC8300DD29B8 /* OFCollection.h in Headers */, 4B674400163C395900EB1E59 /* OFCondition.h in Headers */, 4B3D23C11337FC8300DD29B8 /* OFConstantString.h in Headers */, 4B45355313DCFE1E0037AB4D /* OFCountedSet.h in Headers */, 4B3D23C91337FCB000DD29B8 /* OFCryptoHash.h in Headers */, - 4B3D23C21337FC8300DD29B8 /* OFDataArray.h in Headers */, - 4B3D23C31337FC8300DD29B8 /* OFDataArray+CryptoHashing.h in Headers */, - 4B879A8C177231F000EBCEA4 /* OFDataArray+MessagePackValue.h in Headers */, + 4B3D23C21337FC8300DD29B8 /* OFData.h in Headers */, + 4B3D23C31337FC8300DD29B8 /* OFData+CryptoHashing.h in Headers */, + 4B879A8C177231F000EBCEA4 /* OFData+MessagePackValue.h in Headers */, 4B3D23C41337FC8300DD29B8 /* OFDate.h in Headers */, 4B3D23C51337FCB000DD29B8 /* OFDictionary.h in Headers */, 4B3D23C61337FCB000DD29B8 /* OFEnumerator.h in Headers */, 4B17FF74133A2AAB003E6DCD /* OFException.h in Headers */, 4B3D23C81337FCB000DD29B8 /* OFFile.h in Headers */, @@ -2695,10 +2699,11 @@ 4B3B0798166978780044E634 /* OFMapTable.h in Headers */, 4B3D23CC1337FCB000DD29B8 /* OFMD5Hash.h in Headers */, 4BCAA9AF1772432F003EF859 /* OFMessagePackExtension.h in Headers */, 4B879A8E177231F000EBCEA4 /* OFMessagePackRepresentation.h in Headers */, 4B3D23CD1337FCB000DD29B8 /* OFMutableArray.h in Headers */, + 4B1223151F23E6C000D9F8FF /* OFMutableData.h in Headers */, 4B3D23CE1337FCB000DD29B8 /* OFMutableDictionary.h in Headers */, 4B39844713D3AFB400E6F825 /* OFMutableSet.h in Headers */, 4B3D23CF1337FCB000DD29B8 /* OFMutableString.h in Headers */, 4B4116D01F21654200E78916 /* OFMutableURL.h in Headers */, 4B674403163C395900EB1E59 /* OFMutex.h in Headers */, @@ -2844,10 +2849,11 @@ 4B2B3E7D140D430500EC2F7C /* OFArray_adjacent.h in Headers */, 4B9BB7BD141CDE2D000AD1CC /* OFArray_adjacentSubarray.h in Headers */, 4B9BB7BF141CDE2D000AD1CC /* OFArray_subarray.h in Headers */, 4B1473CB17E6391900B46BB8 /* OFAutoreleasePool+Private.h in Headers */, 4BA85BCA140ECCE800E91D51 /* OFCountedSet_hashtable.h in Headers */, + 4B1223141F23E6C000D9F8FF /* OFData+Private.h in Headers */, 4B2B3E7F140D430500EC2F7C /* OFDictionary_hashtable.h in Headers */, 4B06855518B2AD3800FC731A /* OFINICategory+Private.h in Headers */, 4B0EA9231898690E00F573A4 /* OFKernelEventObserver+Private.h in Headers */, 4B0EA91B1898690E00F573A4 /* OFKernelEventObserver_kqueue.h in Headers */, 4B0EA91D1898690E00F573A4 /* OFKernelEventObserver_poll.h in Headers */, @@ -3216,19 +3222,18 @@ 4B2C21201DA292BE00735907 /* OFArray.m in Sources */, 4B2C21211DA292BE00735907 /* OFArray_adjacent.m in Sources */, 4B2C21221DA292BE00735907 /* OFArray_adjacentSubarray.m in Sources */, 4B2C21231DA292BE00735907 /* OFArray_subarray.m in Sources */, 4B2C21241DA292BE00735907 /* OFAutoreleasePool.m in Sources */, - 4B2C21251DA292BE00735907 /* OFBigDataArray.m in Sources */, 4B2C21261DA292BE00735907 /* OFBlock.m in Sources */, 4B2C21271DA292BE00735907 /* OFCondition.m in Sources */, 4B2C21281DA292BE00735907 /* OFConstantString.m in Sources */, 4B2C21291DA292BE00735907 /* OFCountedSet.m in Sources */, 4B2C212A1DA292BE00735907 /* OFCountedSet_hashtable.m in Sources */, - 4B2C212B1DA292BE00735907 /* OFDataArray.m in Sources */, - 4B2C212C1DA292BE00735907 /* OFDataArray+CryptoHashing.m in Sources */, - 4B2C212D1DA292BE00735907 /* OFDataArray+MessagePackValue.m in Sources */, + 4B2C212B1DA292BE00735907 /* OFData.m in Sources */, + 4B2C212C1DA292BE00735907 /* OFData+CryptoHashing.m in Sources */, + 4B2C212D1DA292BE00735907 /* OFData+MessagePackValue.m in Sources */, 4B2C212E1DA292BE00735907 /* OFDate.m in Sources */, 4B2C21311DA292BE00735907 /* OFDictionary.m in Sources */, 4B2C21321DA292BE00735907 /* OFDictionary_hashtable.m in Sources */, 4B2C21331DA292BE00735907 /* OFEnumerator.m in Sources */, 4B2C21341DA292BE00735907 /* OFFile.m in Sources */, @@ -3255,10 +3260,11 @@ 4B2C21451DA292BE00735907 /* OFMapTable.m in Sources */, 4B2C21461DA292BE00735907 /* OFMD5Hash.m in Sources */, 4B2C21471DA292BE00735907 /* OFMessagePackExtension.m in Sources */, 4B2C21481DA292BE00735907 /* OFMutableArray.m in Sources */, 4B2C21491DA292BE00735907 /* OFMutableArray_adjacent.m in Sources */, + 4B1223191F23E6C100D9F8FF /* OFMutableData.m in Sources */, 4B2C214A1DA292BE00735907 /* OFMutableDictionary.m in Sources */, 4B2C214B1DA292BE00735907 /* OFMutableDictionary_hashtable.m in Sources */, 4B2C214C1DA292BE00735907 /* OFMutableSet.m in Sources */, 4B2C214D1DA292BE00735907 /* OFMutableSet_hashtable.m in Sources */, 4B2C214E1DA292BE00735907 /* OFMutableString.m in Sources */, @@ -3416,19 +3422,18 @@ 4B3D238C1337FC0D00DD29B8 /* OFArray.m in Sources */, 4B2B3E7E140D430500EC2F7C /* OFArray_adjacent.m in Sources */, 4B9BB7BE141CDE2D000AD1CC /* OFArray_adjacentSubarray.m in Sources */, 4B9BB7C0141CDE2D000AD1CC /* OFArray_subarray.m in Sources */, 4B3D238D1337FC0D00DD29B8 /* OFAutoreleasePool.m in Sources */, - 4BF48CE218A95F83000E8D04 /* OFBigDataArray.m in Sources */, 4B3D238E1337FC0D00DD29B8 /* OFBlock.m in Sources */, 4B674401163C395900EB1E59 /* OFCondition.m in Sources */, 4B3D238F1337FC0D00DD29B8 /* OFConstantString.m in Sources */, 4B45355413DCFE1E0037AB4D /* OFCountedSet.m in Sources */, 4BA85BCB140ECCE800E91D51 /* OFCountedSet_hashtable.m in Sources */, - 4B3D23901337FC0D00DD29B8 /* OFDataArray.m in Sources */, - 4B3D23911337FC0D00DD29B8 /* OFDataArray+CryptoHashing.m in Sources */, - 4B879A8D177231F000EBCEA4 /* OFDataArray+MessagePackValue.m in Sources */, + 4B3D23901337FC0D00DD29B8 /* OFData.m in Sources */, + 4B3D23911337FC0D00DD29B8 /* OFData+CryptoHashing.m in Sources */, + 4B879A8D177231F000EBCEA4 /* OFData+MessagePackValue.m in Sources */, 4B3D23921337FC0D00DD29B8 /* OFDate.m in Sources */, 4B3D23931337FC0D00DD29B8 /* OFDictionary.m in Sources */, 4B2B3E80140D430500EC2F7C /* OFDictionary_hashtable.m in Sources */, 4B3D23941337FC0D00DD29B8 /* OFEnumerator.m in Sources */, 4B3D23961337FC0D00DD29B8 /* OFFile.m in Sources */, @@ -3455,10 +3460,11 @@ 4B3B0799166978780044E634 /* OFMapTable.m in Sources */, 4B3D239A1337FC0D00DD29B8 /* OFMD5Hash.m in Sources */, 4BCAA9B01772432F003EF859 /* OFMessagePackExtension.m in Sources */, 4B3D239B1337FC0D00DD29B8 /* OFMutableArray.m in Sources */, 4B2B3E82140D430500EC2F7C /* OFMutableArray_adjacent.m in Sources */, + 4B1223161F23E6C000D9F8FF /* OFMutableData.m in Sources */, 4B3D239C1337FC0D00DD29B8 /* OFMutableDictionary.m in Sources */, 4B2B3E84140D430500EC2F7C /* OFMutableDictionary_hashtable.m in Sources */, 4B39844813D3AFB400E6F825 /* OFMutableSet.m in Sources */, 4BA85BCD140ECCE800E91D51 /* OFMutableSet_hashtable.m in Sources */, 4B3D239D1337FC0D00DD29B8 /* OFMutableString.m in Sources */, @@ -3622,11 +3628,11 @@ buildActionMask = 2147483647; files = ( 4BD9CA001DA2C5FC00E5AD52 /* ForwardingTests.m in Sources */, 4BD9CA011DA2C5FE00E5AD52 /* OFArrayTests.m in Sources */, 4BD9CA021DA2C60200E5AD52 /* OFBlockTests.m in Sources */, - 4BD9CA031DA2C60400E5AD52 /* OFDataArrayTests.m in Sources */, + 4BD9CA031DA2C60400E5AD52 /* OFDataTests.m in Sources */, 4BD9CA041DA2C60700E5AD52 /* OFDateTests.m in Sources */, 4BD9CA051DA2C60900E5AD52 /* OFDictionaryTests.m in Sources */, 4BD9CA061DA2C60B00E5AD52 /* OFHMACTests.m in Sources */, 4BD9CA071DA2C60E00E5AD52 /* OFHTTPClientTests.m in Sources */, 4BD9CA081DA2C61900E5AD52 /* OFHTTPCookieTests.m in Sources */, @@ -3668,11 +3674,11 @@ buildActionMask = 2147483647; files = ( 4BA4846615CC9FAD00D75360 /* ForwardingTests.m in Sources */, 4BF33AFC133807A20059CEF7 /* OFArrayTests.m in Sources */, 4BF33AFD133807A20059CEF7 /* OFBlockTests.m in Sources */, - 4BF33AFE133807A20059CEF7 /* OFDataArrayTests.m in Sources */, + 4BF33AFE133807A20059CEF7 /* OFDataTests.m in Sources */, 4BF33AFF133807A20059CEF7 /* OFDateTests.m in Sources */, 4BF33B00133807A20059CEF7 /* OFDictionaryTests.m in Sources */, 4BF0DD741D44645D001D9949 /* OFHMACTests.m in Sources */, 4BB4B54A16776094002A2DCE /* OFHTTPClientTests.m in Sources */, 4B2610C61D86305C001F16C9 /* OFHTTPCookieTests.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -10,17 +10,16 @@ LIB_MINOR = ${OBJFW_LIB_MINOR} SRCS = OFApplication.m \ OFArray.m \ OFAutoreleasePool.m \ - OFBigDataArray.m \ OFBlock.m \ OFConstantString.m \ OFCountedSet.m \ - OFDataArray.m \ - OFDataArray+CryptoHashing.m \ - OFDataArray+MessagePackValue.m \ + OFData.m \ + OFData+CryptoHashing.m \ + OFData+MessagePackValue.m \ OFDate.m \ OFDictionary.m \ OFEnumerator.m \ OFGZIPStream.m \ OFHMAC.m \ @@ -35,10 +34,11 @@ OFLocalization.m \ OFMapTable.m \ OFMD5Hash.m \ OFMessagePackExtension.m \ OFMutableArray.m \ + OFMutableData.m \ OFMutableDictionary.m \ OFMutableSet.m \ OFMutableString.m \ OFMutableURL.m \ OFNull.m \ Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -24,11 +24,11 @@ #import "OFArray.h" #import "OFArray_subarray.h" #import "OFArray_adjacent.h" #import "OFString.h" #import "OFXMLElement.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFNull.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" @@ -654,17 +654,17 @@ objc_autoreleasePoolPop(pool); return JSON; } -- (OFDataArray *)messagePackRepresentation +- (OFData *)messagePackRepresentation { - OFDataArray *data; + OFMutableData *data; size_t i, count; void *pool; - data = [OFDataArray dataArray]; + data = [OFMutableData data]; count = [self count]; if (count <= 15) { uint8_t tmp = 0x90 | ((uint8_t)count & 0xF); [data addItem: &tmp]; @@ -688,11 +688,11 @@ pool = objc_autoreleasePoolPush(); i = 0; for (id object in self) { void *pool2 = objc_autoreleasePoolPush(); - OFDataArray *child; + OFData *child; i++; child = [object messagePackRepresentation]; [data addItems: [child items] @@ -700,10 +700,12 @@ objc_autoreleasePoolPop(pool2); } assert(i == count); + + [data makeImmutable]; objc_autoreleasePoolPop(pool); return data; } Index: src/OFArray_adjacent.h ================================================================== --- src/OFArray_adjacent.h +++ src/OFArray_adjacent.h @@ -16,14 +16,14 @@ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN -@class OFDataArray; +@class OFMutableData; @interface OFArray_adjacent: OFArray { - OFDataArray *_array; + OFMutableData *_array; } @end OF_ASSUME_NONNULL_END Index: src/OFArray_adjacent.m ================================================================== --- src/OFArray_adjacent.m +++ src/OFArray_adjacent.m @@ -19,11 +19,11 @@ #include #import "OFArray_adjacent.h" #import "OFMutableArray_adjacent.h" #import "OFArray_adjacentSubarray.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" @@ -33,11 +33,11 @@ - init { self = [super init]; @try { - _array = [[OFDataArray alloc] initWithItemSize: sizeof(id)]; + _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)]; } @catch (id e) { [self release]; @throw e; } @@ -97,12 +97,12 @@ @try { objects = [array objects]; count = [array count]; - _array = [[OFDataArray alloc] initWithItemSize: sizeof(id) - capacity: count]; + _array = [[OFMutableData alloc] initWithItemSize: sizeof(id) + capacity: count]; } @catch (id e) { [self release]; @throw e; } DELETED src/OFBigDataArray.h Index: src/OFBigDataArray.h ================================================================== --- src/OFBigDataArray.h +++ src/OFBigDataArray.h @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFDataArray.h" - -OF_ASSUME_NONNULL_BEGIN - -/*! - * @class OFBigDataArray OFBigDataArray.h ObjFW/OFBigDataArray.h - * - * @brief A class for storing arbitrary big data in an array. - * - * The OFBigDataArray class is a class for storing arbitrary data in an array - * and is designed to store large hunks of data. Therefore, it allocates - * memory in pages rather than a chunk of memory for each item. - */ -@interface OFBigDataArray: OFDataArray -{ - size_t _size; -} -@end - -OF_ASSUME_NONNULL_END DELETED src/OFBigDataArray.m Index: src/OFBigDataArray.m ================================================================== --- src/OFBigDataArray.m +++ src/OFBigDataArray.m @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFBigDataArray.h" -#import "OFSystemInfo.h" - -#import "OFInvalidArgumentException.h" -#import "OFOutOfMemoryException.h" -#import "OFOutOfRangeException.h" - -@implementation OFBigDataArray -- init -{ - return [self initWithItemSize: 1 - capacity: 0]; -} - -- initWithItemSize: (size_t)itemSize -{ - return [self initWithItemSize: itemSize - capacity: 0]; -} - -- initWithItemSize: (size_t)itemSize - capacity: (size_t)capacity -{ - self = [super init]; - - @try { - size_t size, pageSize; - - if (itemSize == 0) - @throw [OFInvalidArgumentException exception]; - - if (capacity > SIZE_MAX / itemSize) - @throw [OFOutOfRangeException exception]; - - pageSize = [OFSystemInfo pageSize]; - size = OF_ROUND_UP_POW2(pageSize, capacity * itemSize); - - if (size == 0) - size = pageSize; - - _items = [self allocMemoryWithSize: size]; - - _itemSize = itemSize; - _capacity = size / itemSize; - _size = size; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)addItem: (const void *)item -{ - if (SIZE_MAX - _count < 1 || _count + 1 > SIZE_MAX / _itemSize) - @throw [OFOutOfRangeException exception]; - - if (_count + 1 > _capacity) { - size_t size, pageSize; - - pageSize = [OFSystemInfo pageSize]; - size = OF_ROUND_UP_POW2(pageSize, (_count + 1) * _itemSize); - - _items = [self resizeMemory: _items - size: size]; - - _capacity = size / _itemSize; - _size = size; - } - - memcpy(_items + _count * _itemSize, item, _itemSize); - - _count++; -} - -- (void)addItems: (const void *)items - count: (size_t)count -{ - if (count > SIZE_MAX - _count || _count + count > SIZE_MAX / _itemSize) - @throw [OFOutOfRangeException exception]; - - if (_count + count > _capacity) { - size_t size, pageSize; - - pageSize = [OFSystemInfo pageSize]; - size = OF_ROUND_UP_POW2(pageSize, (_count + count) * _itemSize); - - _items = [self resizeMemory: _items - size: size]; - - _capacity = size / _itemSize; - _size = size; - } - - memcpy(_items + _count * _itemSize, items, count * _itemSize); - - _count += count; -} - -- (void)insertItems: (const void *)items - atIndex: (size_t)index - count: (size_t)count -{ - if (count > SIZE_MAX - _count || index > _count || - _count + count > SIZE_MAX / _itemSize) - @throw [OFOutOfRangeException exception]; - - if (_count + count > _capacity) { - size_t size, pageSize; - - pageSize = [OFSystemInfo pageSize]; - size = OF_ROUND_UP_POW2(pageSize, (_count + count) * _itemSize); - - _items = [self resizeMemory: _items - size: size]; - - _capacity = size / _itemSize; - _size = size; - } - - memmove(_items + (index + count) * _itemSize, - _items + index * _itemSize, (_count - index) * _itemSize); - memcpy(_items + index * _itemSize, items, count * _itemSize); - - _count += count; -} - -- (void)removeItemsInRange: (of_range_t)range -{ - size_t pageSize, size; - - if (range.length > SIZE_MAX - range.location || - range.location + range.length > _count) - @throw [OFOutOfRangeException exception]; - - memmove(_items + range.location * _itemSize, - _items + (range.location + range.length) * _itemSize, - (_count - range.location - range.length) * _itemSize); - - _count -= range.length; - pageSize = [OFSystemInfo pageSize]; - size = OF_ROUND_UP_POW2(pageSize, _count * _itemSize); - - if (_size != size && size >= pageSize) { - @try { - _items = [self resizeMemory: _items - size: size]; - _capacity = size / _itemSize; - _size = size; - } @catch (OFOutOfMemoryException *e) { - /* We don't care, as we only made it smaller */ - } - } -} - -- (void)removeLastItem -{ - size_t pageSize, size; - - if (_count == 0) - return; - - _count--; - pageSize = [OFSystemInfo pageSize]; - size = OF_ROUND_UP_POW2(pageSize, _count * _itemSize); - - if (_size != size && size >= pageSize) { - @try { - _items = [self resizeMemory: _items - size: size]; - _capacity = size / _itemSize; - _size = size; - } @catch (OFOutOfMemoryException *e) { - /* We don't care, as we only made it smaller */ - } - } -} - -- (void)removeAllItems -{ - size_t pageSize = [OFSystemInfo pageSize]; - - @try { - _items = [self resizeMemory: _items - size: pageSize]; - _capacity = pageSize / _itemSize; - _size = pageSize; - } @catch (OFOutOfMemoryException *e) { - /* We don't care, as we only made it smaller */ - } - - _count = 0; -} -@end ADDED src/OFData+CryptoHashing.h Index: src/OFData+CryptoHashing.h ================================================================== --- src/OFData+CryptoHashing.h +++ src/OFData+CryptoHashing.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFData.h" + +OF_ASSUME_NONNULL_BEGIN + +@class OFString; + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFData_CryptoHashing_reference; +#ifdef __cplusplus +} +#endif + +@interface OFData (CryptoHashing) +/*! + * @brief Returns the MD5 hash of the data array as an autoreleased OFString. + * + * @return The MD5 hash of the data array as an autoreleased OFString + */ +- (OFString *)MD5Hash; + +/*! + * @brief Returns the RIPEMD-160 hash of the data array as an autoreleased + * OFString. + * + * @return The RIPEMD-160 hash of the data array as an autoreleased OFString + */ +- (OFString *)RIPEMD160Hash; + +/*! + * @brief Returns the SHA-1 hash of the data array as an autoreleased OFString. + * + * @return The SHA-1 hash of the data array as an autoreleased OFString + */ +- (OFString *)SHA1Hash; + +/*! + * @brief Returns the SHA-224 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-224 hash of the data array as an autoreleased OFString + */ +- (OFString *)SHA224Hash; + +/*! + * @brief Returns the SHA-256 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-256 hash of the data array as an autoreleased OFString + */ +- (OFString *)SHA256Hash; + +/*! + * @brief Returns the SHA-384 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-384 hash of the data array as an autoreleased OFString + */ +- (OFString *)SHA384Hash; + +/*! + * @brief Returns the SHA-512 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-512 hash of the data array as an autoreleased OFString + */ +- (OFString *)SHA512Hash; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFData+CryptoHashing.m Index: src/OFData+CryptoHashing.m ================================================================== --- src/OFData+CryptoHashing.m +++ src/OFData+CryptoHashing.m @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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" + +#import "OFData+CryptoHashing.h" +#import "OFString.h" +#import "OFCryptoHash.h" +#import "OFMD5Hash.h" +#import "OFRIPEMD160Hash.h" +#import "OFSHA1Hash.h" +#import "OFSHA224Hash.h" +#import "OFSHA256Hash.h" +#import "OFSHA384Hash.h" +#import "OFSHA512Hash.h" + +int _OFData_CryptoHashing_reference; + +@implementation OFData (CryptoHashing) +- (OFString *)of_cryptoHashWithClass: (Class )class +{ + void *pool = objc_autoreleasePoolPush(); + id hash = [class cryptoHash]; + size_t digestSize = [class digestSize]; + const unsigned char *digest; + char cString[digestSize * 2]; + + [hash updateWithBuffer: _items + length: _count * _itemSize]; + digest = [hash digest]; + + for (size_t i = 0; i < digestSize; i++) { + uint8_t high, low; + + high = digest[i] >> 4; + low = digest[i] & 0x0F; + + cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0'); + cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0'); + } + + objc_autoreleasePoolPop(pool); + + return [OFString stringWithCString: cString + encoding: OF_STRING_ENCODING_ASCII + length: digestSize * 2]; +} + +- (OFString *)MD5Hash +{ + return [self of_cryptoHashWithClass: [OFMD5Hash class]]; +} + +- (OFString *)RIPEMD160Hash +{ + return [self of_cryptoHashWithClass: [OFRIPEMD160Hash class]]; +} + +- (OFString *)SHA1Hash +{ + return [self of_cryptoHashWithClass: [OFSHA1Hash class]]; +} + +- (OFString *)SHA224Hash +{ + return [self of_cryptoHashWithClass: [OFSHA224Hash class]]; +} + +- (OFString *)SHA256Hash +{ + return [self of_cryptoHashWithClass: [OFSHA256Hash class]]; +} + +- (OFString *)SHA384Hash +{ + return [self of_cryptoHashWithClass: [OFSHA384Hash class]]; +} + +- (OFString *)SHA512Hash +{ + return [self of_cryptoHashWithClass: [OFSHA512Hash class]]; +} +@end ADDED src/OFData+MessagePackValue.h Index: src/OFData+MessagePackValue.h ================================================================== --- src/OFData+MessagePackValue.h +++ src/OFData+MessagePackValue.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFData.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFData_MessagePackValue_reference; +#ifdef __cplusplus +} +#endif + +@interface OFData (MessagePackValue) +/*! + * @brief Parses the MessagePack representation and returns it as an object. + * + * @return The MessagePack representation as an object + */ +- (id)messagePackValue; + +/*! + * @brief Parses the MessagePack representation and returns it as an object. + * + * @param depthLimit The maximum depth the parser should accept (defaults to 32 + * if not specified, 0 means no limit (insecure!)) + * @return The MessagePack representation as an object + */ +- (id)messagePackValueWithDepthLimit: (size_t)depthLimit; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFData+MessagePackValue.m Index: src/OFData+MessagePackValue.m ================================================================== --- src/OFData+MessagePackValue.m +++ src/OFData+MessagePackValue.m @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFData+MessagePackValue.h" +#import "OFNumber.h" +#import "OFNull.h" +#import "OFString.h" +#import "OFArray.h" +#import "OFDictionary.h" +#import "OFMessagePackExtension.h" + +#import "OFInvalidFormatException.h" + +int _OFData_MessagePackValue_reference; + +static size_t parseObject(const uint8_t *buffer, size_t length, id *object, + size_t depthLimit); + +static uint16_t +readUInt16(const uint8_t *buffer) +{ + return ((uint16_t)buffer[0] << 8) | buffer[1]; +} + +static uint32_t +readUInt32(const uint8_t *buffer) +{ + return ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | + ((uint32_t)buffer[2] << 8) | buffer[3]; +} + +static uint64_t +readUInt64(const uint8_t *buffer) +{ + return ((uint64_t)buffer[0] << 56) | ((uint64_t)buffer[1] << 48) | + ((uint64_t)buffer[2] << 40) | ((uint64_t)buffer[3] << 32) | + ((uint64_t)buffer[4] << 24) | ((uint64_t)buffer[5] << 16) | + ((uint64_t)buffer[6] << 8) | buffer[7]; +} + +static size_t +parseArray(const uint8_t *buffer, size_t length, id *object, size_t count, + size_t depthLimit) +{ + void *pool; + size_t pos = 0; + + if (--depthLimit == 0) { + *object = nil; + return 0; + } + + /* + * Don't use capacity! For data and strings, this is safe, as we can + * check if we still have enough bytes left. For an array however, we + * can't know this, as every child can be more than one byte. + */ + *object = [OFMutableArray array]; + + for (size_t i = 0; i < count; i++) { + id child; + size_t childLength; + + pool = objc_autoreleasePoolPush(); + + childLength = parseObject(buffer + pos, length - pos, &child, + depthLimit); + if (childLength == 0 || child == nil) { + objc_autoreleasePoolPop(pool); + + *object = nil; + return 0; + } + pos += childLength; + + [*object addObject: child]; + + objc_autoreleasePoolPop(pool); + } + + return pos; +} + +static size_t +parseTable(const uint8_t *buffer, size_t length, id *object, size_t count, + size_t depthLimit) +{ + void *pool; + size_t pos = 0; + + if (--depthLimit == 0) { + *object = nil; + return 0; + } + + /* + * Don't use capacity! For data and strings, this is safe, as we can + * check if we still have enough bytes left. For a dictionary however, + * we can't know this, as every key / value can be more than one byte. + */ + *object = [OFMutableDictionary dictionary]; + + for (size_t i = 0; i < count; i++) { + id key, value; + size_t keyLength, valueLength; + + pool = objc_autoreleasePoolPush(); + + keyLength = parseObject(buffer + pos, length - pos, &key, + depthLimit); + if (keyLength == 0 || key == nil) { + objc_autoreleasePoolPop(pool); + + *object = nil; + return 0; + } + pos += keyLength; + + valueLength = parseObject(buffer + pos, length - pos, &value, + depthLimit); + if (valueLength == 0 || value == nil) { + objc_autoreleasePoolPop(pool); + + *object = nil; + return 0; + } + pos += valueLength; + + [*object setObject: value + forKey: key]; + + objc_autoreleasePoolPop(pool); + } + + return pos; +} + +static size_t +parseObject(const uint8_t *buffer, size_t length, id *object, + size_t depthLimit) +{ + size_t count; + int8_t type; + OFData *data; + + if (length < 1) + goto error; + + /* positive fixint */ + if ((buffer[0] & 0x80) == 0) { + *object = [OFNumber numberWithUInt8: buffer[0] & 0x7F]; + return 1; + } + /* negative fixint */ + if ((buffer[0] & 0xE0) == 0xE0) { + *object = [OFNumber numberWithInt8: + ((int8_t)(buffer[0] & 0x1F)) - 32]; + return 1; + } + + /* fixstr */ + if ((buffer[0] & 0xE0) == 0xA0) { + count = buffer[0] & 0x1F; + + if (length < count + 1) + goto error; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 1 + length: count]; + return count + 1; + } + + /* fixarray */ + if ((buffer[0] & 0xF0) == 0x90) + return parseArray(buffer + 1, length - 1, object, + buffer[0] & 0xF, depthLimit) + 1; + + /* fixmap */ + if ((buffer[0] & 0xF0) == 0x80) + return parseTable(buffer + 1, length - 1, object, + buffer[0] & 0xF, depthLimit) + 1; + + /* Prefix byte */ + switch (buffer[0]) { + /* Unsigned integers */ + case 0xCC: /* uint8 */ + if (length < 2) + goto error; + + *object = [OFNumber numberWithUInt8: buffer[1]]; + return 2; + case 0xCD: /* uint 16 */ + if (length < 3) + goto error; + + *object = [OFNumber numberWithUInt16: readUInt16(buffer + 1)]; + return 3; + case 0xCE: /* uint 32 */ + if (length < 5) + goto error; + + *object = [OFNumber numberWithUInt32: readUInt32(buffer + 1)]; + return 5; + case 0xCF: /* uint 64 */ + if (length < 9) + goto error; + + *object = [OFNumber numberWithUInt64: readUInt64(buffer + 1)]; + return 9; + /* Signed integers */ + case 0xD0: /* int 8 */ + if (length < 2) + goto error; + + *object = [OFNumber numberWithInt8: buffer[1]]; + return 2; + case 0xD1: /* int 16 */ + if (length < 3) + goto error; + + *object = [OFNumber numberWithInt16: readUInt16(buffer + 1)]; + return 3; + case 0xD2: /* int 32 */ + if (length < 5) + goto error; + + *object = [OFNumber numberWithInt32: readUInt32(buffer + 1)]; + return 5; + case 0xD3: /* int 64 */ + if (length < 9) + goto error; + + *object = [OFNumber numberWithInt64: readUInt64(buffer + 1)]; + return 9; + /* Floating point */ + case 0xCA:; /* float 32 */ + union { + uint8_t u8[4]; + float f; + } f; + + if (length < 5) + goto error; + + memcpy(&f.u8, buffer + 1, 4); + + *object = [OFNumber numberWithFloat: OF_BSWAP_FLOAT_IF_LE(f.f)]; + return 5; + case 0xCB:; /* float 64 */ + union { + uint8_t u8[8]; + double d; + } d; + + if (length < 9) + goto error; + + memcpy(&d.u8, buffer + 1, 8); + + *object = [OFNumber numberWithDouble: + OF_BSWAP_DOUBLE_IF_LE(d.d)]; + return 9; + /* nil */ + case 0xC0: + *object = [OFNull null]; + return 1; + /* false */ + case 0xC2: + *object = [OFNumber numberWithBool: false]; + return 1; + /* true */ + case 0xC3: + *object = [OFNumber numberWithBool: true]; + return 1; + /* Data */ + case 0xC4: /* bin 8 */ + if (length < 2) + goto error; + + count = buffer[1]; + + if (length < count + 2) + goto error; + + *object = [OFData dataWithItems: buffer + 2 + count: count]; + + return count + 2; + case 0xC5: /* bin 16 */ + if (length < 3) + goto error; + + count = readUInt16(buffer + 1); + + if (length < count + 3) + goto error; + + *object = [OFData dataWithItems: buffer + 3 + count: count]; + + return count + 3; + case 0xC6: /* bin 32 */ + if (length < 5) + goto error; + + count = readUInt32(buffer + 1); + + if (length < count + 5) + goto error; + + *object = [OFData dataWithItems: buffer + 5 + count: count]; + + return count + 5; + /* Extensions */ + case 0xC7: /* ext 8 */ + if (length < 3) + goto error; + + count = buffer[1]; + + if (length < count + 3) + goto error; + + type = buffer[2]; + + data = [[OFData alloc] initWithItems: buffer + 3 + count: count]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return count + 3; + case 0xC8: /* ext 16 */ + if (length < 4) + goto error; + + count = readUInt16(buffer + 1); + + if (length < count + 4) + goto error; + + type = buffer[3]; + + data = [[OFData alloc] initWithItems: buffer + 4 + count: count]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return count + 4; + case 0xC9: /* ext 32 */ + if (length < 6) + goto error; + + count = readUInt32(buffer + 1); + + if (length < count + 6) + goto error; + + type = buffer[5]; + + data = [[OFData alloc] initWithItems: buffer + 6 + count: count]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return count + 6; + case 0xD4: /* fixext 1 */ + if (length < 3) + goto error; + + type = buffer[1]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 1]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return 3; + case 0xD5: /* fixext 2 */ + if (length < 4) + goto error; + + type = buffer[1]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 2]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return 4; + case 0xD6: /* fixext 4 */ + if (length < 6) + goto error; + + type = buffer[1]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 4]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return 6; + case 0xD7: /* fixext 8 */ + if (length < 10) + goto error; + + type = buffer[1]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 8]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return 10; + case 0xD8: /* fixext 16 */ + if (length < 18) + goto error; + + type = buffer[1]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 16]; + @try { + *object = [OFMessagePackExtension + extensionWithType: type + data: data]; + } @finally { + [data release]; + } + + return 18; + /* Strings */ + case 0xD9: /* str 8 */ + if (length < 2) + goto error; + + count = buffer[1]; + + if (length < count + 2) + goto error; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 2 + length: count]; + return count + 2; + case 0xDA: /* str 16 */ + if (length < 3) + goto error; + + count = readUInt16(buffer + 1); + + if (length < count + 3) + goto error; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 3 + length: count]; + return count + 3; + case 0xDB: /* str 32 */ + if (length < 5) + goto error; + + count = readUInt32(buffer + 1); + + if (length < count + 5) + goto error; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 5 + length: count]; + return count + 5; + /* Arrays */ + case 0xDC: /* array 16 */ + if (length < 3) + goto error; + + return parseArray(buffer + 3, length - 3, object, + readUInt16(buffer + 1), depthLimit) + 3; + case 0xDD: /* array 32 */ + if (length < 5) + goto error; + + return parseArray(buffer + 5, length - 5, object, + readUInt32(buffer + 1), depthLimit) + 5; + /* Maps */ + case 0xDE: /* map 16 */ + if (length < 3) + goto error; + + return parseTable(buffer + 3, length - 3, object, + readUInt16(buffer + 1), depthLimit) + 3; + case 0xDF: /* map 32 */ + if (length < 5) + goto error; + + return parseTable(buffer + 5, length - 5, object, + readUInt32(buffer + 1), depthLimit) + 5; + } + +error: + *object = nil; + return 0; +} + +@implementation OFData (MessagePackValue) +- (id)messagePackValue +{ + return [self messagePackValueWithDepthLimit: 32]; +} + +- (id)messagePackValueWithDepthLimit: (size_t)depthLimit +{ + void *pool = objc_autoreleasePoolPush(); + size_t count = [self count]; + id object; + + if (parseObject([self items], count, &object, depthLimit) != count || + object == nil) + @throw [OFInvalidFormatException exception]; + + [object retain]; + + objc_autoreleasePoolPop(pool); + + return object; +} +@end ADDED src/OFData+Private.h Index: src/OFData+Private.h ================================================================== --- src/OFData+Private.h +++ src/OFData+Private.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFData.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OFData () +- (instancetype)of_init OF_METHOD_FAMILY(init); +@end + +OF_ASSUME_NONNULL_END ADDED src/OFData.h Index: src/OFData.h ================================================================== --- src/OFData.h +++ src/OFData.h @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFObject.h" +#import "OFSerialization.h" +#import "OFMessagePackRepresentation.h" + +OF_ASSUME_NONNULL_BEGIN + +@class OFString; +@class OFURL; + +/*! + * @class OFData OFData.h ObjFW/OFData.h + * + * @brief A class for storing arbitrary data in an array. + * + * For security reasons, serialization and deserialization is only implemented + * for OFData with item size 1. + */ +@interface OFData: OFObject +{ + char *_items; + size_t _count, _itemSize; + bool _freeWhenDone; +} + +/*! + * The size of a single item in the OFData in bytes. + */ +@property (readonly, nonatomic) size_t itemSize; + +/*! + * @brief Creates a new OFData with the specified `count` items of size 1. + * + * @param items The items to store in the OFData + * @param count The number of items + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithItems: (const void *)items + count: (size_t)count; + +/*! + * @brief Creates a new OFData with the specified `count` items of the + * specified size. + * + * @param items The items to store in the OFData + * @param itemSize The item size of a single item in bytes + * @param count The number of items + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithItems: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count; + +/*! + * @brief Creates a new OFData with the specified `count` items of size 1 by + * taking over ownership of the specified items pointer. + * + * @param items The items to store in the OFData + * @param count The number of items + * @param freeWhenDone Whether to free the pointer when it is no longer needed + * by the OFData + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone; + +/*! + * @brief Creates a new OFData with the specified `count` items of the + * specified size by taking ownership of the specified items pointer. + * + * @param items The items to store in the OFData + * @param itemSize The item size of a single item in bytes + * @param count The number of items + * @param freeWhenDone Whether to free the pointer when it is no longer needed + * by the OFData + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone; + +#ifdef OF_HAVE_FILES +/*! + * @brief Creates a new OFData with an item size of 1, containing the data of + * the specified file. + * + * @param path The path of the file + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithContentsOfFile: (OFString *)path; +#endif + +#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) +/*! + * @brief Creates a new OFData with an item size of 1, containing the data of + * the specified URL. + * + * @param URL The URL to the contents for the OFData + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithContentsOfURL: (OFURL *)URL; +#endif + +/*! + * @brief Creates a new OFData with an item size of 1, containing the data of + * the string representation. + * + * @param string The string representation of the data + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithStringRepresentation: (OFString *)string; + +/*! + * @brief Creates a new OFData with an item size of 1, containing the data of + * the Base64-encoded string. + * + * @param string The string with the Base64-encoded data + * @return A new autoreleased OFData + */ ++ (instancetype)dataWithBase64EncodedString: (OFString *)string; + +- init OF_UNAVAILABLE; + +/*! + * @brief Initialized an already allocated OFData with the specified `count` + * items of size 1. + * + * @param items The items to store in the OFData + * @param count The number of items + * @return An initialized OFData + */ +- initWithItems: (const void *)items + count: (size_t)count; + +/*! + * @brief Initialized an already allocated OFData with the specified `count` + * items of the specified size. + * + * @param items The items to store in the OFData + * @param itemSize The item size of a single item in bytes + * @param count The number of items + * @return An initialized OFData + */ +- initWithItems: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count; + +/*! + * @brief Initializes an already allocated OFData with the specified `count` + * items of size 1 by taking over ownership of the specified items + * pointer. + * + * @param items The items to store in the OFData + * @param count The number of items + * @param freeWhenDone Whether to free the pointer when it is no longer needed + * by the OFData + * @return An initialized OFData + */ +- initWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone; + +/*! + * @brief Initializes an already allocated OFData with the specified `count` + * items of the specified size by taking ownership of the specified + * items pointer. + * + * @param items The items to store in the OFData + * @param itemSize The item size of a single item in bytes + * @param count The number of items + * @param freeWhenDone Whether to free the pointer when it is no longer needed + * by the OFData + * @return An initialized OFData + */ +- initWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone; + +#ifdef OF_HAVE_FILES +/*! + * @brief Initializes an already allocated OFData with an item size of 1, + * containing the data of the specified file. + * + * @param path The path of the file + * @return An initialized OFData + */ +- initWithContentsOfFile: (OFString *)path; +#endif + +#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) +/*! + * @brief Initializes an already allocated OFData with an item size of 1, + * containing the data of the specified URL. + * + * @param URL The URL to the contents for the OFData + * @return A new autoreleased OFData + */ +- initWithContentsOfURL: (OFURL *)URL; +#endif + +/*! + * @brief Initializes an already allocated OFData with an item size of 1, + * containing the data of the string representation. + * + * @param string The string representation of the data + * @return A new autoreleased OFData + */ +- initWithStringRepresentation: (OFString *)string; + +/*! + * @brief Initializes an already allocated OFData with an item size of 1, + * containing the data of the Base64-encoded string. + * + * @param string The string with the Base64-encoded data + * @return An initialized OFData + */ +- initWithBase64EncodedString: (OFString *)string; + +/*! + * @brief Returns the number of items in the OFData. + * + * @return The number of items in the OFData + */ +- (size_t)count; + +/*! + * @brief Returns all items of the OFData as a C array. + * + * @warning The pointer is only valid until the OFData is changed! + * + * @return All elements of the OFData as a C array + */ +- (const void *)items OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns a specific item of the OFData. + * + * @param index The number of the item to return + * @return The specified item of the OFData + */ +- (const void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns the first item of the OFData. + * + * @return The first item of the OFData or NULL + */ +- (nullable const void *)firstItem OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns the last item of the OFData. + * + * @return The last item of the OFData or NULL + */ +- (nullable const void *)lastItem OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns the string representation of the data. + * + * The string representation is a hex dump of the data, grouped by itemSize + * bytes. + * + * @return The string representation of the data. + */ +- (OFString *)stringRepresentation; + +/*! + * @brief Returns a string containing the data in Base64 encoding. + * + * @return A string containing the data in Base64 encoding + */ +- (OFString *)stringByBase64Encoding; + +#ifdef OF_HAVE_FILES +/*! + * @brief Writes the OFData into the specified file. + * + * @param path The path of the file to write to + */ +- (void)writeToFile: (OFString *)path; +#endif +@end + +OF_ASSUME_NONNULL_END + +#import "OFMutableData.h" +#import "OFData+CryptoHashing.h" +#import "OFData+MessagePackValue.h" ADDED src/OFData.m Index: src/OFData.m ================================================================== --- src/OFData.m +++ src/OFData.m @@ -0,0 +1,675 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 +#include +#include + +#import "OFData.h" +#import "OFData+Private.h" +#import "OFString.h" +#ifdef OF_HAVE_FILES +# import "OFFile.h" +# import "OFFileManager.h" +#endif +#import "OFURL.h" +#ifdef OF_HAVE_SOCKETS +# import "OFHTTPClient.h" +# import "OFHTTPRequest.h" +# import "OFHTTPResponse.h" +#endif +#import "OFDictionary.h" +#import "OFXMLElement.h" +#import "OFSystemInfo.h" + +#ifdef OF_HAVE_SOCKETS +# import "OFHTTPRequestFailedException.h" +#endif +#import "OFInvalidArgumentException.h" +#import "OFInvalidFormatException.h" +#import "OFInvalidServerReplyException.h" +#import "OFOutOfMemoryException.h" +#import "OFOutOfRangeException.h" +#import "OFTruncatedDataException.h" +#import "OFUnsupportedProtocolException.h" + +#import "base64.h" + +/* References for static linking */ +void +_references_to_categories_of_OFData(void) +{ + _OFData_CryptoHashing_reference = 1; + _OFData_MessagePackValue_reference = 1; +} + +@implementation OFData +@synthesize itemSize = _itemSize; + ++ (instancetype)dataWithItems: (const void *)items + count: (size_t)count +{ + return [[[self alloc] initWithItems: items + count: count] autorelease]; +} + ++ (instancetype)dataWithItems: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count +{ + return [[[self alloc] initWithItems: items + itemSize: itemSize + count: count] autorelease]; +} + ++ (instancetype)dataWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + return [[[self alloc] initWithItemsNoCopy: items + count: count + freeWhenDone: freeWhenDone] autorelease]; +} + ++ (instancetype)dataWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + return [[[self alloc] initWithItemsNoCopy: items + itemSize: itemSize + count: count + freeWhenDone: freeWhenDone] autorelease]; +} + +#ifdef OF_HAVE_FILES ++ (instancetype)dataWithContentsOfFile: (OFString *)path +{ + return [[[self alloc] initWithContentsOfFile: path] autorelease]; +} +#endif + +#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) ++ (instancetype)dataWithContentsOfURL: (OFURL *)URL +{ + return [[[self alloc] initWithContentsOfURL: URL] autorelease]; +} +#endif + ++ (instancetype)dataWithStringRepresentation: (OFString *)string +{ + return [[[self alloc] + initWithStringRepresentation: string] autorelease]; +} + ++ (instancetype)dataWithBase64EncodedString: (OFString *)string +{ + return [[[self alloc] initWithBase64EncodedString: string] autorelease]; +} + +- init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)of_init +{ + return [super init]; +} + +- initWithItems: (const void *)items + count: (size_t)count +{ + return [self initWithItems: items + itemSize: 1 + count: count]; +} + +- initWithItems: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count +{ + self = [super init]; + + @try { + if (itemSize == 0) + @throw [OFInvalidArgumentException exception]; + + _itemSize = itemSize; + _count = count; + _items = [self allocMemoryWithSize: itemSize + count: count]; + + memcpy(_items, items, itemSize * count); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + return [self initWithItemsNoCopy: items + itemSize: 1 + count: count + freeWhenDone: freeWhenDone]; +} + +- initWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + self = [super init]; + + @try { + if (itemSize == 0) + @throw [OFInvalidArgumentException exception]; + + _items = (char *)items; + _itemSize = itemSize; + _count = count; + _freeWhenDone = freeWhenDone; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +#ifdef OF_HAVE_FILES +- initWithContentsOfFile: (OFString *)path +{ + @try { + of_offset_t size = [[OFFileManager defaultManager] + sizeOfFileAtPath: path]; + char *buffer; + + if (sizeof(of_offset_t) > sizeof(size_t) && + size > (of_offset_t)SIZE_MAX) + @throw [OFOutOfRangeException exception]; + + buffer = malloc(size); + if (buffer == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: size]; + + @try { + OFFile *file = [[OFFile alloc] initWithPath: path + mode: @"rb"]; + @try { + [file readIntoBuffer: buffer + exactLength: size]; + } @finally { + [file release]; + } + + self = [self initWithItemsNoCopy: buffer + count: size + freeWhenDone: true]; + } @catch (id e) { + free(buffer); + @throw e; + } + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} +#endif + +#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) +- initWithContentsOfURL: (OFURL *)URL +{ + void *pool; + OFString *scheme; + + pool = objc_autoreleasePoolPush(); + + scheme = [URL scheme]; + +# ifdef OF_HAVE_FILES + if ([scheme isEqual: @"file"]) + self = [self initWithContentsOfFile: [URL path]]; + else +# endif +# ifdef OF_HAVE_SOCKETS + if ([scheme isEqual: @"http"] || [scheme isEqual: @"https"]) { + bool mutable = [self isKindOfClass: [OFMutableData class]]; + + if (!mutable) { + [self release]; + self = [OFMutableData alloc]; + } + + self = [(OFMutableData *)self init]; + + @try { + OFHTTPClient *client = [OFHTTPClient client]; + OFHTTPRequest *request = [OFHTTPRequest + requestWithURL: URL]; + OFHTTPResponse *response = [client + performRequest: request]; + size_t pageSize; + char *buffer; + OFDictionary *headers; + OFString *contentLengthString; + + if ([response statusCode] != 200) + @throw [OFHTTPRequestFailedException + exceptionWithRequest: request + response: response]; + + pageSize = [OFSystemInfo pageSize]; + buffer = [self allocMemoryWithSize: pageSize]; + + @try { + while (![response isAtEndOfStream]) { + size_t length; + + length = [response + readIntoBuffer: buffer + length: pageSize]; + [(OFMutableData *)self + addItems: buffer + count: length]; + } + } @finally { + [self freeMemory: buffer]; + } + + headers = [response headers]; + if ((contentLengthString = + [headers objectForKey: @"Content-Length"]) != nil) { + intmax_t contentLength = + [contentLengthString decimalValue]; + + if (contentLength < 0) + @throw [OFInvalidServerReplyException + exception]; + + if ((uintmax_t)[self count] != + (uintmax_t)contentLength) + @throw [OFTruncatedDataException + exception]; + } + } @catch (id e) { + [self release]; + @throw e; + } + + if (!mutable) + [(OFMutableData *)self makeImmutable]; + } else +# endif + @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; + + objc_autoreleasePoolPop(pool); + + return self; +} +#endif + +- initWithStringRepresentation: (OFString *)string +{ + self = [super init]; + + @try { + size_t count = [string + cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII]; + const char *cString; + + if (count % 2 != 0) + @throw [OFInvalidFormatException exception]; + + count /= 2; + + _items = [self allocMemoryWithSize: count]; + _itemSize = 1; + _count = count; + + cString = [string + cStringWithEncoding: OF_STRING_ENCODING_ASCII]; + + for (size_t i = 0; i < count; i++) { + uint8_t c1 = cString[2 * i]; + uint8_t c2 = cString[2 * i + 1]; + uint8_t byte; + + if (c1 >= '0' && c1 <= '9') + byte = (c1 - '0') << 4; + else if (c1 >= 'a' && c1 <= 'f') + byte = (c1 - 'a' + 10) << 4; + else if (c1 >= 'A' && c1 <= 'F') + byte = (c1 - 'A' + 10) << 4; + else + @throw [OFInvalidFormatException exception]; + + if (c2 >= '0' && c2 <= '9') + byte |= c2 - '0'; + else if (c2 >= 'a' && c2 <= 'f') + byte |= c2 - 'a' + 10; + else if (c2 >= 'A' && c2 <= 'F') + byte |= c2 - 'A' + 10; + else + @throw [OFInvalidFormatException exception]; + + _items[i] = byte; + } + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithBase64EncodedString: (OFString *)string +{ + bool mutable = [self isKindOfClass: [OFMutableData class]]; + + if (!mutable) { + [self release]; + self = [OFMutableData alloc]; + } + + self = [(OFMutableData *)self initWithCapacity: [string length] / 3]; + + @try { + if (!of_base64_decode((OFMutableData *)self, + [string cStringWithEncoding: OF_STRING_ENCODING_ASCII], + [string cStringLengthWithEncoding: + OF_STRING_ENCODING_ASCII])) + @throw [OFInvalidFormatException exception]; + } @catch (id e) { + [self release]; + @throw e; + } + + if (!mutable) + [(OFMutableData *)self makeImmutable]; + + return self; +} + +- initWithSerialization: (OFXMLElement *)element +{ + @try { + void *pool = objc_autoreleasePoolPush(); + OFString *stringValue; + + if (![[element name] isEqual: [self className]] || + ![[element namespace] isEqual: OF_SERIALIZATION_NS]) + @throw [OFInvalidArgumentException exception]; + + stringValue = [element stringValue]; + + self = [self initWithBase64EncodedString: stringValue]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + if (_freeWhenDone) + free(_items); + + [super dealloc]; +} + +- (size_t)count +{ + return _count; +} + +- (const void *)items +{ + return _items; +} + +- (const void *)itemAtIndex: (size_t)index +{ + if (index >= _count) + @throw [OFOutOfRangeException exception]; + + return _items + index * _itemSize; +} + +- (const void *)firstItem +{ + if (_items == NULL || _count == 0) + return NULL; + + return _items; +} + +- (const void *)lastItem +{ + if (_items == NULL || _count == 0) + return NULL; + + return _items + (_count - 1) * _itemSize; +} + +- copy +{ + return [self retain]; +} + +- mutableCopy +{ + return [[OFMutableData alloc] initWithItems: _items + itemSize: _itemSize + count: _count]; +} + +- (bool)isEqual: (id)object +{ + OFData *data; + + if (![object isKindOfClass: [OFData class]]) + return false; + + data = object; + + if ([data count] != _count || [data itemSize] != _itemSize) + return false; + if (memcmp([data items], _items, _count * _itemSize) != 0) + return false; + + return true; +} + +- (of_comparison_result_t)compare: (id )object +{ + OFData *data; + int comparison; + size_t count, minCount; + + if (![object isKindOfClass: [OFData class]]) + @throw [OFInvalidArgumentException exception]; + + data = (OFData *)object; + + if ([data itemSize] != _itemSize) + @throw [OFInvalidArgumentException exception]; + + count = [data count]; + minCount = (_count > count ? count : _count); + + if ((comparison = memcmp(_items, [data items], + minCount * _itemSize)) == 0) { + if (_count > count) + return OF_ORDERED_DESCENDING; + if (_count < count) + return OF_ORDERED_ASCENDING; + + return OF_ORDERED_SAME; + } + + if (comparison > 0) + return OF_ORDERED_DESCENDING; + else + return OF_ORDERED_ASCENDING; +} + +- (uint32_t)hash +{ + uint32_t hash; + + OF_HASH_INIT(hash); + + for (size_t i = 0; i < _count * _itemSize; i++) + OF_HASH_ADD(hash, ((uint8_t *)_items)[i]); + + OF_HASH_FINALIZE(hash); + + return hash; +} + +- (OFString *)description +{ + OFMutableString *ret = [OFMutableString stringWithString: @"<"]; + + for (size_t i = 0; i < _count; i++) { + if (i > 0) + [ret appendString: @" "]; + + for (size_t j = 0; j < _itemSize; j++) + [ret appendFormat: @"%02x", _items[i * _itemSize + j]]; + } + + [ret appendString: @">"]; + + [ret makeImmutable]; + return ret; +} + +- (OFString *)stringRepresentation +{ + OFMutableString *ret = [OFMutableString string]; + + for (size_t i = 0; i < _count; i++) + for (size_t j = 0; j < _itemSize; j++) + [ret appendFormat: @"%02x", _items[i * _itemSize + j]]; + + [ret makeImmutable]; + return ret; +} + +- (OFString *)stringByBase64Encoding +{ + return of_base64_encode(_items, _count * _itemSize); +} + +#ifdef OF_HAVE_FILES +- (void)writeToFile: (OFString *)path +{ + OFFile *file = [[OFFile alloc] initWithPath: path + mode: @"wb"]; + + @try { + [file writeBuffer: _items + length: _count * _itemSize]; + } @finally { + [file release]; + } +} +#endif + +- (OFXMLElement *)XMLElementBySerializing +{ + void *pool; + OFXMLElement *element; + + if (_itemSize != 1) + @throw [OFInvalidArgumentException exception]; + + pool = objc_autoreleasePoolPush(); + element = [OFXMLElement + elementWithName: [self className] + namespace: OF_SERIALIZATION_NS + stringValue: of_base64_encode(_items, _count * _itemSize)]; + + [element retain]; + + objc_autoreleasePoolPop(pool); + + return [element autorelease]; +} + +- (OFData *)messagePackRepresentation +{ + OFMutableData *data; + + if (_itemSize != 1) + @throw [OFInvalidArgumentException exception]; + + if (_count <= UINT8_MAX) { + uint8_t type = 0xC4; + uint8_t tmp = (uint8_t)_count; + + data = [OFMutableData dataWithItemSize: 1 + capacity: _count + 2]; + + [data addItem: &type]; + [data addItem: &tmp]; + } else if (_count <= UINT16_MAX) { + uint8_t type = 0xC5; + uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)_count); + + data = [OFMutableData dataWithItemSize: 1 + capacity: _count + 3]; + + [data addItem: &type]; + [data addItems: &tmp + count: sizeof(tmp)]; + } else if (_count <= UINT32_MAX) { + uint8_t type = 0xC6; + uint32_t tmp = OF_BSWAP32_IF_LE((uint32_t)_count); + + data = [OFMutableData dataWithItemSize: 1 + capacity: _count + 5]; + + [data addItem: &type]; + [data addItems: &tmp + count: sizeof(tmp)]; + } else + @throw [OFOutOfRangeException exception]; + + [data addItems: _items + count: _count]; + + [data makeImmutable]; + + return data; +} +@end DELETED src/OFDataArray+CryptoHashing.h Index: src/OFDataArray+CryptoHashing.h ================================================================== --- src/OFDataArray+CryptoHashing.h +++ src/OFDataArray+CryptoHashing.h @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFDataArray.h" - -OF_ASSUME_NONNULL_BEGIN - -@class OFString; - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFDataArray_CryptoHashing_reference; -#ifdef __cplusplus -} -#endif - -@interface OFDataArray (CryptoHashing) -/*! - * @brief Returns the MD5 hash of the data array as an autoreleased OFString. - * - * @return The MD5 hash of the data array as an autoreleased OFString - */ -- (OFString *)MD5Hash; - -/*! - * @brief Returns the RIPEMD-160 hash of the data array as an autoreleased - * OFString. - * - * @return The RIPEMD-160 hash of the data array as an autoreleased OFString - */ -- (OFString *)RIPEMD160Hash; - -/*! - * @brief Returns the SHA-1 hash of the data array as an autoreleased OFString. - * - * @return The SHA-1 hash of the data array as an autoreleased OFString - */ -- (OFString *)SHA1Hash; - -/*! - * @brief Returns the SHA-224 hash of the data array as an autoreleased - * OFString. - * - * @return The SHA-224 hash of the data array as an autoreleased OFString - */ -- (OFString *)SHA224Hash; - -/*! - * @brief Returns the SHA-256 hash of the data array as an autoreleased - * OFString. - * - * @return The SHA-256 hash of the data array as an autoreleased OFString - */ -- (OFString *)SHA256Hash; - -/*! - * @brief Returns the SHA-384 hash of the data array as an autoreleased - * OFString. - * - * @return The SHA-384 hash of the data array as an autoreleased OFString - */ -- (OFString *)SHA384Hash; - -/*! - * @brief Returns the SHA-512 hash of the data array as an autoreleased - * OFString. - * - * @return The SHA-512 hash of the data array as an autoreleased OFString - */ -- (OFString *)SHA512Hash; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFDataArray+CryptoHashing.m Index: src/OFDataArray+CryptoHashing.m ================================================================== --- src/OFDataArray+CryptoHashing.m +++ src/OFDataArray+CryptoHashing.m @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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" - -#import "OFDataArray.h" -#import "OFString.h" -#import "OFCryptoHash.h" -#import "OFMD5Hash.h" -#import "OFRIPEMD160Hash.h" -#import "OFSHA1Hash.h" -#import "OFSHA224Hash.h" -#import "OFSHA256Hash.h" -#import "OFSHA384Hash.h" -#import "OFSHA512Hash.h" - -int _OFDataArray_CryptoHashing_reference; - -@implementation OFDataArray (Hashing) -- (OFString *)of_cryptoHashWithClass: (Class )class -{ - void *pool = objc_autoreleasePoolPush(); - id hash = [class cryptoHash]; - size_t digestSize = [class digestSize]; - const unsigned char *digest; - char cString[digestSize * 2]; - - [hash updateWithBuffer: _items - length: _count * _itemSize]; - digest = [hash digest]; - - for (size_t i = 0; i < digestSize; i++) { - uint8_t high, low; - - high = digest[i] >> 4; - low = digest[i] & 0x0F; - - cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0'); - cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0'); - } - - objc_autoreleasePoolPop(pool); - - return [OFString stringWithCString: cString - encoding: OF_STRING_ENCODING_ASCII - length: digestSize * 2]; -} - -- (OFString *)MD5Hash -{ - return [self of_cryptoHashWithClass: [OFMD5Hash class]]; -} - -- (OFString *)RIPEMD160Hash -{ - return [self of_cryptoHashWithClass: [OFRIPEMD160Hash class]]; -} - -- (OFString *)SHA1Hash -{ - return [self of_cryptoHashWithClass: [OFSHA1Hash class]]; -} - -- (OFString *)SHA224Hash -{ - return [self of_cryptoHashWithClass: [OFSHA224Hash class]]; -} - -- (OFString *)SHA256Hash -{ - return [self of_cryptoHashWithClass: [OFSHA256Hash class]]; -} - -- (OFString *)SHA384Hash -{ - return [self of_cryptoHashWithClass: [OFSHA384Hash class]]; -} - -- (OFString *)SHA512Hash -{ - return [self of_cryptoHashWithClass: [OFSHA512Hash class]]; -} -@end DELETED src/OFDataArray+MessagePackValue.h Index: src/OFDataArray+MessagePackValue.h ================================================================== --- src/OFDataArray+MessagePackValue.h +++ src/OFDataArray+MessagePackValue.h @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFDataArray.h" - -OF_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFDataArray_MessagePackValue_reference; -#ifdef __cplusplus -} -#endif - -@interface OFDataArray (MessagePackValue) -/*! - * @brief Parses the MessagePack representation and returns it as an object. - * - * @return The MessagePack representation as an object - */ -- (id)messagePackValue; - -/*! - * @brief Parses the MessagePack representation and returns it as an object. - * - * @param depthLimit The maximum depth the parser should accept (defaults to 32 - * if not specified, 0 means no limit (insecure!)) - * @return The MessagePack representation as an object - */ -- (id)messagePackValueWithDepthLimit: (size_t)depthLimit; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFDataArray+MessagePackValue.m Index: src/OFDataArray+MessagePackValue.m ================================================================== --- src/OFDataArray+MessagePackValue.m +++ src/OFDataArray+MessagePackValue.m @@ -1,599 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFDataArray+MessagePackValue.h" -#import "OFNumber.h" -#import "OFNull.h" -#import "OFDataArray.h" -#import "OFString.h" -#import "OFArray.h" -#import "OFDictionary.h" -#import "OFMessagePackExtension.h" - -#import "OFInvalidFormatException.h" - -int _OFDataArray_MessagePackValue_reference; - -static size_t parseObject(const uint8_t *buffer, size_t length, id *object, - size_t depthLimit); - -static uint16_t -readUInt16(const uint8_t *buffer) -{ - return ((uint16_t)buffer[0] << 8) | buffer[1]; -} - -static uint32_t -readUInt32(const uint8_t *buffer) -{ - return ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | - ((uint32_t)buffer[2] << 8) | buffer[3]; -} - -static uint64_t -readUInt64(const uint8_t *buffer) -{ - return ((uint64_t)buffer[0] << 56) | ((uint64_t)buffer[1] << 48) | - ((uint64_t)buffer[2] << 40) | ((uint64_t)buffer[3] << 32) | - ((uint64_t)buffer[4] << 24) | ((uint64_t)buffer[5] << 16) | - ((uint64_t)buffer[6] << 8) | buffer[7]; -} - -static size_t -parseArray(const uint8_t *buffer, size_t length, id *object, size_t count, - size_t depthLimit) -{ - void *pool; - size_t pos = 0; - - if (--depthLimit == 0) { - *object = nil; - return 0; - } - - /* - * Don't use capacity! For data and strings, this is safe, as we can - * check if we still have enough bytes left. For an array however, we - * can't know this, as every child can be more than one byte. - */ - *object = [OFMutableArray array]; - - for (size_t i = 0; i < count; i++) { - id child; - size_t childLength; - - pool = objc_autoreleasePoolPush(); - - childLength = parseObject(buffer + pos, length - pos, &child, - depthLimit); - if (childLength == 0 || child == nil) { - objc_autoreleasePoolPop(pool); - - *object = nil; - return 0; - } - pos += childLength; - - [*object addObject: child]; - - objc_autoreleasePoolPop(pool); - } - - return pos; -} - -static size_t -parseTable(const uint8_t *buffer, size_t length, id *object, size_t count, - size_t depthLimit) -{ - void *pool; - size_t pos = 0; - - if (--depthLimit == 0) { - *object = nil; - return 0; - } - - /* - * Don't use capacity! For data and strings, this is safe, as we can - * check if we still have enough bytes left. For a dictionary however, - * we can't know this, as every key / value can be more than one byte. - */ - *object = [OFMutableDictionary dictionary]; - - for (size_t i = 0; i < count; i++) { - id key, value; - size_t keyLength, valueLength; - - pool = objc_autoreleasePoolPush(); - - keyLength = parseObject(buffer + pos, length - pos, &key, - depthLimit); - if (keyLength == 0 || key == nil) { - objc_autoreleasePoolPop(pool); - - *object = nil; - return 0; - } - pos += keyLength; - - valueLength = parseObject(buffer + pos, length - pos, &value, - depthLimit); - if (valueLength == 0 || value == nil) { - objc_autoreleasePoolPop(pool); - - *object = nil; - return 0; - } - pos += valueLength; - - [*object setObject: value - forKey: key]; - - objc_autoreleasePoolPop(pool); - } - - return pos; -} - -static size_t -parseObject(const uint8_t *buffer, size_t length, id *object, - size_t depthLimit) -{ - size_t count; - int8_t type; - OFDataArray *data; - - if (length < 1) - goto error; - - /* positive fixint */ - if ((buffer[0] & 0x80) == 0) { - *object = [OFNumber numberWithUInt8: buffer[0] & 0x7F]; - return 1; - } - /* negative fixint */ - if ((buffer[0] & 0xE0) == 0xE0) { - *object = [OFNumber numberWithInt8: - ((int8_t)(buffer[0] & 0x1F)) - 32]; - return 1; - } - - /* fixstr */ - if ((buffer[0] & 0xE0) == 0xA0) { - count = buffer[0] & 0x1F; - - if (length < count + 1) - goto error; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 1 - length: count]; - return count + 1; - } - - /* fixarray */ - if ((buffer[0] & 0xF0) == 0x90) - return parseArray(buffer + 1, length - 1, object, - buffer[0] & 0xF, depthLimit) + 1; - - /* fixmap */ - if ((buffer[0] & 0xF0) == 0x80) - return parseTable(buffer + 1, length - 1, object, - buffer[0] & 0xF, depthLimit) + 1; - - /* Prefix byte */ - switch (buffer[0]) { - /* Unsigned integers */ - case 0xCC: /* uint8 */ - if (length < 2) - goto error; - - *object = [OFNumber numberWithUInt8: buffer[1]]; - return 2; - case 0xCD: /* uint 16 */ - if (length < 3) - goto error; - - *object = [OFNumber numberWithUInt16: readUInt16(buffer + 1)]; - return 3; - case 0xCE: /* uint 32 */ - if (length < 5) - goto error; - - *object = [OFNumber numberWithUInt32: readUInt32(buffer + 1)]; - return 5; - case 0xCF: /* uint 64 */ - if (length < 9) - goto error; - - *object = [OFNumber numberWithUInt64: readUInt64(buffer + 1)]; - return 9; - /* Signed integers */ - case 0xD0: /* int 8 */ - if (length < 2) - goto error; - - *object = [OFNumber numberWithInt8: buffer[1]]; - return 2; - case 0xD1: /* int 16 */ - if (length < 3) - goto error; - - *object = [OFNumber numberWithInt16: readUInt16(buffer + 1)]; - return 3; - case 0xD2: /* int 32 */ - if (length < 5) - goto error; - - *object = [OFNumber numberWithInt32: readUInt32(buffer + 1)]; - return 5; - case 0xD3: /* int 64 */ - if (length < 9) - goto error; - - *object = [OFNumber numberWithInt64: readUInt64(buffer + 1)]; - return 9; - /* Floating point */ - case 0xCA:; /* float 32 */ - union { - uint8_t u8[4]; - float f; - } f; - - if (length < 5) - goto error; - - memcpy(&f.u8, buffer + 1, 4); - - *object = [OFNumber numberWithFloat: OF_BSWAP_FLOAT_IF_LE(f.f)]; - return 5; - case 0xCB:; /* float 64 */ - union { - uint8_t u8[8]; - double d; - } d; - - if (length < 9) - goto error; - - memcpy(&d.u8, buffer + 1, 8); - - *object = [OFNumber numberWithDouble: - OF_BSWAP_DOUBLE_IF_LE(d.d)]; - return 9; - /* nil */ - case 0xC0: - *object = [OFNull null]; - return 1; - /* false */ - case 0xC2: - *object = [OFNumber numberWithBool: false]; - return 1; - /* true */ - case 0xC3: - *object = [OFNumber numberWithBool: true]; - return 1; - /* Data */ - case 0xC4: /* bin 8 */ - if (length < 2) - goto error; - - count = buffer[1]; - - if (length < count + 2) - goto error; - - *object = [OFDataArray dataArrayWithCapacity: count]; - [*object addItems: buffer + 2 - count: count]; - - return count + 2; - case 0xC5: /* bin 16 */ - if (length < 3) - goto error; - - count = readUInt16(buffer + 1); - - if (length < count + 3) - goto error; - - *object = [OFDataArray dataArrayWithCapacity: count]; - [*object addItems: buffer + 3 - count: count]; - - return count + 3; - case 0xC6: /* bin 32 */ - if (length < 5) - goto error; - - count = readUInt32(buffer + 1); - - if (length < count + 5) - goto error; - - *object = [OFDataArray dataArrayWithCapacity: count]; - [*object addItems: buffer + 5 - count: count]; - - return count + 5; - /* Extensions */ - case 0xC7: /* ext 8 */ - if (length < 3) - goto error; - - count = buffer[1]; - - if (length < count + 3) - goto error; - - type = buffer[2]; - - data = [[OFDataArray alloc] initWithCapacity: count]; - @try { - [data addItems: buffer + 3 - count: count]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return count + 3; - case 0xC8: /* ext 16 */ - if (length < 4) - goto error; - - count = readUInt16(buffer + 1); - - if (length < count + 4) - goto error; - - type = buffer[3]; - - data = [[OFDataArray alloc] initWithCapacity: count]; - @try { - [data addItems: buffer + 4 - count: count]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return count + 4; - case 0xC9: /* ext 32 */ - if (length < 6) - goto error; - - count = readUInt32(buffer + 1); - - if (length < count + 6) - goto error; - - type = buffer[5]; - - data = [[OFDataArray alloc] initWithCapacity: count]; - @try { - [data addItems: buffer + 6 - count: count]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return count + 6; - case 0xD4: /* fixext 1 */ - if (length < 3) - goto error; - - type = buffer[1]; - - data = [[OFDataArray alloc] initWithCapacity: 1]; - @try { - [data addItem: buffer + 2]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return 3; - case 0xD5: /* fixext 2 */ - if (length < 4) - goto error; - - type = buffer[1]; - - data = [[OFDataArray alloc] initWithCapacity: 2]; - @try { - [data addItems: buffer + 2 - count: 2]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return 4; - case 0xD6: /* fixext 4 */ - if (length < 6) - goto error; - - type = buffer[1]; - - data = [[OFDataArray alloc] initWithCapacity: 4]; - @try { - [data addItems: buffer + 2 - count: 4]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return 6; - case 0xD7: /* fixext 8 */ - if (length < 10) - goto error; - - type = buffer[1]; - - data = [[OFDataArray alloc] initWithCapacity: 8]; - @try { - [data addItems: buffer + 2 - count: 8]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return 10; - case 0xD8: /* fixext 16 */ - if (length < 18) - goto error; - - type = buffer[1]; - - data = [[OFDataArray alloc] initWithCapacity: 16]; - @try { - [data addItems: buffer + 2 - count: 16]; - - *object = [OFMessagePackExtension - extensionWithType: type - data: data]; - } @finally { - [data release]; - } - - return 18; - /* Strings */ - case 0xD9: /* str 8 */ - if (length < 2) - goto error; - - count = buffer[1]; - - if (length < count + 2) - goto error; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 2 - length: count]; - return count + 2; - case 0xDA: /* str 16 */ - if (length < 3) - goto error; - - count = readUInt16(buffer + 1); - - if (length < count + 3) - goto error; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 3 - length: count]; - return count + 3; - case 0xDB: /* str 32 */ - if (length < 5) - goto error; - - count = readUInt32(buffer + 1); - - if (length < count + 5) - goto error; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 5 - length: count]; - return count + 5; - /* Arrays */ - case 0xDC: /* array 16 */ - if (length < 3) - goto error; - - return parseArray(buffer + 3, length - 3, object, - readUInt16(buffer + 1), depthLimit) + 3; - case 0xDD: /* array 32 */ - if (length < 5) - goto error; - - return parseArray(buffer + 5, length - 5, object, - readUInt32(buffer + 1), depthLimit) + 5; - /* Maps */ - case 0xDE: /* map 16 */ - if (length < 3) - goto error; - - return parseTable(buffer + 3, length - 3, object, - readUInt16(buffer + 1), depthLimit) + 3; - case 0xDF: /* map 32 */ - if (length < 5) - goto error; - - return parseTable(buffer + 5, length - 5, object, - readUInt32(buffer + 1), depthLimit) + 5; - } - -error: - *object = nil; - return 0; -} - -@implementation OFDataArray (MessagePackValue) -- (id)messagePackValue -{ - return [self messagePackValueWithDepthLimit: 32]; -} - -- (id)messagePackValueWithDepthLimit: (size_t)depthLimit -{ - void *pool = objc_autoreleasePoolPush(); - size_t count = [self count]; - id object; - - if (parseObject([self items], count, &object, depthLimit) != count || - object == nil) - @throw [OFInvalidFormatException exception]; - - [object retain]; - - objc_autoreleasePoolPop(pool); - - return object; -} -@end DELETED src/OFDataArray.h Index: src/OFDataArray.h ================================================================== --- src/OFDataArray.h +++ src/OFDataArray.h @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFObject.h" -#import "OFSerialization.h" -#import "OFMessagePackRepresentation.h" - -OF_ASSUME_NONNULL_BEGIN - -@class OFString; -@class OFURL; - -/*! - * @class OFDataArray OFDataArray.h ObjFW/OFDataArray.h - * - * @brief A class for storing arbitrary data in an array. - * - * If you plan to store large hunks of data, you should consider using - * OFBigDataArray, which allocates the memory in pages rather than in bytes. - * - * For security reasons, serialization and deserialization is only implemented - * for OFDataArrays with item size 1. - */ -@interface OFDataArray: OFObject -{ - uint8_t *_items; - size_t _count, _itemSize, _capacity; -} - -/*! - * The size of a single item in the OFDataArray in bytes. - */ -@property (readonly, nonatomic) size_t itemSize; - -/*! - * @brief Creates a new OFDataArray with an item size of 1. - * - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArray; - -/*! - * @brief Creates a new OFDataArray whose items all have the same specified - * size. - * - * @param itemSize The size of a single element in the OFDataArray - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithItemSize: (size_t)itemSize; - -/*! - * @brief Creates a new OFDataArray with enough memory to hold the specified - * number of items which all have an item size of 1. - * - * @param capacity The initial capacity for the OFDataArray - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithCapacity: (size_t)capacity; - -/*! - * @brief Creates a new OFDataArray with enough memory to hold the specified - * number of items which all have the same specified size. - * - * @param itemSize The size of a single element in the OFDataArray - * @param capacity The initial capacity for the OFDataArray - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithItemSize: (size_t)itemSize - capacity: (size_t)capacity; - -#ifdef OF_HAVE_FILES -/*! - * @brief Creates a new OFDataArary with an item size of 1, containing the data - * of the specified file. - * - * @param path The path of the file - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithContentsOfFile: (OFString *)path; -#endif - -#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) -/*! - * @brief Creates a new OFDataArray with an item size of 1, containing the data - * of the specified URL. - * - * @param URL The URL to the contents for the OFDataArray - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithContentsOfURL: (OFURL *)URL; -#endif - -/*! - * @brief Creates a new OFDataArray with an item size of 1, containing the data - * of the string representation. - * - * @param string The string representation of the data - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithStringRepresentation: (OFString *)string; - -/*! - * @brief Creates a new OFDataArray with an item size of 1, containing the data - * of the Base64-encoded string. - * - * @param string The string with the Base64-encoded data - * @return A new autoreleased OFDataArray - */ -+ (instancetype)dataArrayWithBase64EncodedString: (OFString *)string; - -/*! - * @brief Initializes an already allocated OFDataArray whose items all have the - * same size. - * - * @param itemSize The size of a single element in the OFDataArray - * @return An initialized OFDataArray - */ -- initWithItemSize: (size_t)itemSize; - -/*! - * @brief Initializes an already allocated OFDataArray with enough memory to - * hold the specified number of items which all have an item size of 1. - * - * @param capacity The initial capacity for the OFDataArray - * @return An initialized OFDataArray - */ -- initWithCapacity: (size_t)capacity; - -/*! - * @brief Initializes an already allocated OFDataArray with enough memory to - * hold the specified number of items which all have the same specified - * size. - * - * @param itemSize The size of a single element in the OFDataArray - * @param capacity The initial capacity for the OFDataArray - * @return An initialized OFDataArray - */ -- initWithItemSize: (size_t)itemSize - capacity: (size_t)capacity; - -#ifdef OF_HAVE_FILES -/*! - * @brief Initializes an already allocated OFDataArray with an item size of 1, - * containing the data of the specified file. - * - * @param path The path of the file - * @return An initialized OFDataArray - */ -- initWithContentsOfFile: (OFString *)path; -#endif - -#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) -/*! - * @brief Initializes an already allocated OFDataArray with an item size of 1, - * containing the data of the specified URL. - * - * @param URL The URL to the contents for the OFDataArray - * @return A new autoreleased OFDataArray - */ -- initWithContentsOfURL: (OFURL *)URL; -#endif - -/*! - * @brief Initializes an already allocated OFDataArray with an item size of 1, - * containing the data of the string representation. - * - * @param string The string representation of the data - * @return A new autoreleased OFDataArray - */ -- initWithStringRepresentation: (OFString *)string; - -/*! - * @brief Initializes an already allocated OFDataArray with an item size of 1, - * containing the data of the Base64-encoded string. - * - * @param string The string with the Base64-encoded data - * @return An initialized OFDataArray - */ -- initWithBase64EncodedString: (OFString *)string; - -/*! - * @brief Returns the number of items in the OFDataArray. - * - * @return The number of items in the OFDataArray - */ -- (size_t)count; - -/*! - * @brief Returns all items of the OFDataArray as a C array. - * - * @warning The pointer is only valid until the OFDataArray is changed! - * - * Modifying the returned array directly is allowed and will change the contents - * of the data array. - * - * @return All elements of the OFDataArray as a C array - */ -- (void *)items OF_RETURNS_INNER_POINTER; - -/*! - * @brief Returns a specific item of the OFDataArray. - * - * @param index The number of the item to return - * @return The specified item of the OFDataArray - */ -- (void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; - -/*! - * @brief Returns the first item of the OFDataArray. - * - * @return The first item of the OFDataArray or NULL - */ -- (nullable void *)firstItem OF_RETURNS_INNER_POINTER; - -/*! - * @brief Returns the last item of the OFDataArray. - * - * @return The last item of the OFDataArray or NULL - */ -- (nullable void *)lastItem OF_RETURNS_INNER_POINTER; - -/*! - * @brief Adds an item to the OFDataArray. - * - * @param item A pointer to an arbitrary item - */ -- (void)addItem: (const void *)item; - -/*! - * @brief Adds an item to the OFDataArray at the specified index. - * - * @param item A pointer to an arbitrary item - * @param index The index where the item should be added - */ -- (void)insertItem: (const void *)item - atIndex: (size_t)index; - -/*! - * @brief Adds items from a C array to the OFDataArray. - * - * @param items A C array containing the items to add - * @param count The number of items to add - */ -- (void)addItems: (const void *)items - count: (size_t)count; - -/*! - * @brief Adds items from a C array to the OFDataArray at the specified index. - * - * @param items A C array containing the items to add - * @param index The index where the items should be added - * @param count The number of items to add - */ -- (void)insertItems: (const void *)items - atIndex: (size_t)index - count: (size_t)count; - -/*! - * @brief Removes the item at the specified index. - * - * @param index The index of the item to remove - */ -- (void)removeItemAtIndex: (size_t)index; - -/*! - * @brief Removes the specified amount of items at the specified index. - * - * @param range The range of items to remove - */ -- (void)removeItemsInRange: (of_range_t)range; - -/*! - * @brief Removes the last item. - */ -- (void)removeLastItem; - -/*! - * @brief Removes all items. - */ -- (void)removeAllItems; - -/*! - * @brief Returns the string representation of the data array. - * - * The string representation is a hex dump of the data inside the data array, - * grouped by itemSize bytes. - * - * @return The string representation of the data array. - */ -- (OFString *)stringRepresentation; - -/*! - * @brief Returns a string containing the data in Base64 encoding. - * - * @return A string containing the data in Base64 encoding - */ -- (OFString *)stringByBase64Encoding; - -#ifdef OF_HAVE_FILES -/*! - * @brief Writes the OFDataArray into the specified file. - * - * @param path The path of the file to write to - */ -- (void)writeToFile: (OFString *)path; -#endif -@end - -OF_ASSUME_NONNULL_END - -#import "OFDataArray+CryptoHashing.h" -#import "OFDataArray+MessagePackValue.h" DELETED src/OFDataArray.m Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -1,711 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 -#include -#include - -#import "OFDataArray.h" -#import "OFString.h" -#ifdef OF_HAVE_FILES -# import "OFFile.h" -# import "OFFileManager.h" -#endif -#import "OFURL.h" -#ifdef OF_HAVE_SOCKETS -# import "OFHTTPClient.h" -# import "OFHTTPRequest.h" -# import "OFHTTPResponse.h" -#endif -#import "OFDictionary.h" -#import "OFXMLElement.h" -#import "OFSystemInfo.h" - -#ifdef OF_HAVE_SOCKETS -# import "OFHTTPRequestFailedException.h" -#endif -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFInvalidServerReplyException.h" -#import "OFOutOfMemoryException.h" -#import "OFOutOfRangeException.h" -#import "OFTruncatedDataException.h" -#import "OFUnsupportedProtocolException.h" - -#import "base64.h" - -/* References for static linking */ -void -_references_to_categories_of_OFDataArray(void) -{ - _OFDataArray_CryptoHashing_reference = 1; - _OFDataArray_MessagePackValue_reference = 1; -} - -@implementation OFDataArray -@synthesize itemSize = _itemSize; - -+ (instancetype)dataArray -{ - return [[[self alloc] init] autorelease]; -} - -+ (instancetype)dataArrayWithItemSize: (size_t)itemSize -{ - return [[[self alloc] initWithItemSize: itemSize] autorelease]; -} - -+ (instancetype)dataArrayWithCapacity: (size_t)capacity -{ - return [[[self alloc] initWithCapacity: capacity] autorelease]; -} - -+ (instancetype)dataArrayWithItemSize: (size_t)itemSize - capacity: (size_t)capacity -{ - return [[[self alloc] initWithItemSize: itemSize - capacity: capacity] autorelease]; -} - -#ifdef OF_HAVE_FILES -+ (instancetype)dataArrayWithContentsOfFile: (OFString *)path -{ - return [[[self alloc] initWithContentsOfFile: path] autorelease]; -} -#endif - -#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) -+ (instancetype)dataArrayWithContentsOfURL: (OFURL *)URL -{ - return [[[self alloc] initWithContentsOfURL: URL] autorelease]; -} -#endif - -+ (instancetype)dataArrayWithStringRepresentation: (OFString *)string -{ - return [[[self alloc] - initWithStringRepresentation: string] autorelease]; -} - -+ (instancetype)dataArrayWithBase64EncodedString: (OFString *)string -{ - return [[[self alloc] initWithBase64EncodedString: string] autorelease]; -} - -- init -{ - self = [super init]; - - _itemSize = 1; - - return self; -} - -- initWithItemSize: (size_t)itemSize -{ - self = [super init]; - - _itemSize = itemSize; - - return self; -} - -- initWithCapacity: (size_t)capacity -{ - return [self initWithItemSize: 1 - capacity: capacity]; -} - -- initWithItemSize: (size_t)itemSize - capacity: (size_t)capacity -{ - self = [super init]; - - @try { - if (itemSize == 0) - @throw [OFInvalidArgumentException exception]; - - _items = [self allocMemoryWithSize: itemSize - count: capacity]; - - _itemSize = itemSize; - _capacity = capacity; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -#ifdef OF_HAVE_FILES -- initWithContentsOfFile: (OFString *)path -{ - @try { - OFFile *file = [[OFFile alloc] initWithPath: path - mode: @"rb"]; - of_offset_t size = [[OFFileManager defaultManager] - sizeOfFileAtPath: path]; - - if (sizeof(of_offset_t) > sizeof(size_t) && - size > (of_offset_t)SIZE_MAX) - @throw [OFOutOfRangeException exception]; - - self = [self initWithItemSize: 1 - capacity: (size_t)size]; - - @try { - size_t pageSize = [OFSystemInfo pageSize]; - char *buffer = [self allocMemoryWithSize: pageSize]; - - while (![file isAtEndOfStream]) { - size_t length; - - length = [file readIntoBuffer: buffer - length: pageSize]; - [self addItems: buffer - count: length]; - } - - [self freeMemory: buffer]; - } @finally { - [file release]; - } - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} -#endif - -#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) -- initWithContentsOfURL: (OFURL *)URL -{ - void *pool; - OFString *scheme; - - pool = objc_autoreleasePoolPush(); - - scheme = [URL scheme]; - -# ifdef OF_HAVE_FILES - if ([scheme isEqual: @"file"]) - self = [self initWithContentsOfFile: [URL path]]; - else -# endif -# ifdef OF_HAVE_SOCKETS - if ([scheme isEqual: @"http"] || [scheme isEqual: @"https"]) { - self = [self init]; - - @try { - OFHTTPClient *client = [OFHTTPClient client]; - OFHTTPRequest *request = [OFHTTPRequest - requestWithURL: URL]; - OFHTTPResponse *response = [client - performRequest: request]; - size_t pageSize; - char *buffer; - OFDictionary *headers; - OFString *contentLengthString; - - if ([response statusCode] != 200) - @throw [OFHTTPRequestFailedException - exceptionWithRequest: request - response: response]; - - pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; - - @try { - while (![response isAtEndOfStream]) { - size_t length; - - length = [response - readIntoBuffer: buffer - length: pageSize]; - [self addItems: buffer - count: length]; - } - } @finally { - [self freeMemory: buffer]; - } - - headers = [response headers]; - if ((contentLengthString = - [headers objectForKey: @"Content-Length"]) != nil) { - intmax_t contentLength = - [contentLengthString decimalValue]; - - if (contentLength < 0) - @throw [OFInvalidServerReplyException - exception]; - - if ((uintmax_t)[self count] != - (uintmax_t)contentLength) - @throw [OFTruncatedDataException - exception]; - } - } @catch (id e) { - [self release]; - @throw e; - } - } else -# endif - @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; - - objc_autoreleasePoolPop(pool); - - return self; -} -#endif - -- initWithStringRepresentation: (OFString *)string -{ - @try { - const char *cString; - size_t count; - - count = [string - cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII]; - - if (count % 2 != 0) - @throw [OFInvalidFormatException exception]; - - count /= 2; - - self = [self initWithCapacity: count]; - - cString = [string - cStringWithEncoding: OF_STRING_ENCODING_ASCII]; - - for (size_t i = 0; i < count; i++) { - uint8_t c1 = cString[2 * i]; - uint8_t c2 = cString[2 * i + 1]; - uint8_t byte; - - if (c1 >= '0' && c1 <= '9') - byte = (c1 - '0') << 4; - else if (c1 >= 'a' && c1 <= 'f') - byte = (c1 - 'a' + 10) << 4; - else if (c1 >= 'A' && c1 <= 'F') - byte = (c1 - 'A' + 10) << 4; - else - @throw [OFInvalidFormatException exception]; - - if (c2 >= '0' && c2 <= '9') - byte |= c2 - '0'; - else if (c2 >= 'a' && c2 <= 'f') - byte |= c2 - 'a' + 10; - else if (c2 >= 'A' && c2 <= 'F') - byte |= c2 - 'A' + 10; - else - @throw [OFInvalidFormatException exception]; - - [self addItem: &byte]; - } - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- initWithBase64EncodedString: (OFString *)string -{ - self = [self initWithItemSize: 1 - capacity: [string length] / 3]; - - @try { - if (!of_base64_decode(self, [string cStringWithEncoding: - OF_STRING_ENCODING_ASCII], [string - cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) - @throw [OFInvalidFormatException exception]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- initWithSerialization: (OFXMLElement *)element -{ - @try { - void *pool = objc_autoreleasePoolPush(); - OFString *stringValue; - - if (![[element name] isEqual: [self className]] || - ![[element namespace] isEqual: OF_SERIALIZATION_NS]) - @throw [OFInvalidArgumentException exception]; - - stringValue = [element stringValue]; - - self = [self initWithBase64EncodedString: stringValue]; - - objc_autoreleasePoolPop(pool); - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (size_t)count -{ - return _count; -} - -- (void *)items -{ - return _items; -} - -- (void *)itemAtIndex: (size_t)index -{ - if (index >= _count) - @throw [OFOutOfRangeException exception]; - - return _items + index * _itemSize; -} - -- (void *)firstItem -{ - if (_items == NULL || _count == 0) - return NULL; - - return _items; -} - -- (void *)lastItem -{ - if (_items == NULL || _count == 0) - return NULL; - - return _items + (_count - 1) * _itemSize; -} - -- (void)addItem: (const void *)item -{ - if (SIZE_MAX - _count < 1) - @throw [OFOutOfRangeException exception]; - - if (_count + 1 > _capacity) { - _items = [self resizeMemory: _items - size: _itemSize - count: _count + 1]; - _capacity = _count + 1; - } - - memcpy(_items + _count * _itemSize, item, _itemSize); - - _count++; -} - -- (void)insertItem: (const void *)item - atIndex: (size_t)index -{ - [self insertItems: item - atIndex: index - count: 1]; -} - -- (void)addItems: (const void *)items - count: (size_t)count -{ - if (count > SIZE_MAX - _count) - @throw [OFOutOfRangeException exception]; - - if (_count + count > _capacity) { - _items = [self resizeMemory: _items - size: _itemSize - count: _count + count]; - _capacity = _count + count; - } - - memcpy(_items + _count * _itemSize, items, count * _itemSize); - _count += count; -} - -- (void)insertItems: (const void *)items - atIndex: (size_t)index - count: (size_t)count -{ - if (count > SIZE_MAX - _count || index > _count) - @throw [OFOutOfRangeException exception]; - - if (_count + count > _capacity) { - _items = [self resizeMemory: _items - size: _itemSize - count: _count + count]; - _capacity = _count + count; - } - - memmove(_items + (index + count) * _itemSize, - _items + index * _itemSize, (_count - index) * _itemSize); - memcpy(_items + index * _itemSize, items, count * _itemSize); - - _count += count; -} - -- (void)removeItemAtIndex: (size_t)index -{ - [self removeItemsInRange: of_range(index, 1)]; -} - -- (void)removeItemsInRange: (of_range_t)range -{ - if (range.length > SIZE_MAX - range.location || - range.location + range.length > _count) - @throw [OFOutOfRangeException exception]; - - memmove(_items + range.location * _itemSize, - _items + (range.location + range.length) * _itemSize, - (_count - range.location - range.length) * _itemSize); - - _count -= range.length; - @try { - _items = [self resizeMemory: _items - size: _itemSize - count: _count]; - _capacity = _count; - } @catch (OFOutOfMemoryException *e) { - /* We don't really care, as we only made it smaller */ - } -} - -- (void)removeLastItem -{ - if (_count == 0) - return; - - _count--; - @try { - _items = [self resizeMemory: _items - size: _itemSize - count: _count]; - _capacity = _count; - } @catch (OFOutOfMemoryException *e) { - /* We don't care, as we only made it smaller */ - } -} - -- (void)removeAllItems -{ - [self freeMemory: _items]; - - _items = NULL; - _count = 0; - _capacity = 0; -} - -- copy -{ - OFDataArray *copy = [[[self class] alloc] initWithItemSize: _itemSize - capacity: _count]; - - [copy addItems: _items - count: _count]; - - return copy; -} - -- (bool)isEqual: (id)object -{ - OFDataArray *dataArray; - - if (![object isKindOfClass: [OFDataArray class]]) - return false; - - dataArray = object; - - if ([dataArray count] != _count || - [dataArray itemSize] != _itemSize) - return false; - if (memcmp([dataArray items], _items, _count * _itemSize) != 0) - return false; - - return true; -} - -- (of_comparison_result_t)compare: (id )object -{ - OFDataArray *dataArray; - int comparison; - size_t count, minCount; - - if (![object isKindOfClass: [OFDataArray class]]) - @throw [OFInvalidArgumentException exception]; - - dataArray = (OFDataArray *)object; - - if ([dataArray itemSize] != _itemSize) - @throw [OFInvalidArgumentException exception]; - - count = [dataArray count]; - minCount = (_count > count ? count : _count); - - if ((comparison = memcmp(_items, [dataArray items], - minCount * _itemSize)) == 0) { - if (_count > count) - return OF_ORDERED_DESCENDING; - if (_count < count) - return OF_ORDERED_ASCENDING; - - return OF_ORDERED_SAME; - } - - if (comparison > 0) - return OF_ORDERED_DESCENDING; - else - return OF_ORDERED_ASCENDING; -} - -- (uint32_t)hash -{ - uint32_t hash; - - OF_HASH_INIT(hash); - - for (size_t i = 0; i < _count * _itemSize; i++) - OF_HASH_ADD(hash, ((uint8_t *)_items)[i]); - - OF_HASH_FINALIZE(hash); - - return hash; -} - -- (OFString *)description -{ - OFMutableString *ret = [OFMutableString stringWithString: @"<"]; - - for (size_t i = 0; i < _count; i++) { - if (i > 0) - [ret appendString: @" "]; - - for (size_t j = 0; j < _itemSize; j++) - [ret appendFormat: @"%02x", _items[i * _itemSize + j]]; - } - - [ret appendString: @">"]; - - [ret makeImmutable]; - return ret; -} - -- (OFString *)stringRepresentation -{ - OFMutableString *ret = [OFMutableString string]; - - for (size_t i = 0; i < _count; i++) - for (size_t j = 0; j < _itemSize; j++) - [ret appendFormat: @"%02x", _items[i * _itemSize + j]]; - - [ret makeImmutable]; - return ret; -} - -- (OFString *)stringByBase64Encoding -{ - return of_base64_encode(_items, _count * _itemSize); -} - -#ifdef OF_HAVE_FILES -- (void)writeToFile: (OFString *)path -{ - OFFile *file = [[OFFile alloc] initWithPath: path - mode: @"wb"]; - - @try { - [file writeBuffer: _items - length: _count * _itemSize]; - } @finally { - [file release]; - } -} -#endif - -- (OFXMLElement *)XMLElementBySerializing -{ - void *pool; - OFXMLElement *element; - - if (_itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - pool = objc_autoreleasePoolPush(); - element = [OFXMLElement - elementWithName: [self className] - namespace: OF_SERIALIZATION_NS - stringValue: of_base64_encode(_items, _count * _itemSize)]; - - [element retain]; - - objc_autoreleasePoolPop(pool); - - return [element autorelease]; -} - -- (OFDataArray *)messagePackRepresentation -{ - OFDataArray *data; - - if (_itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - if (_count <= UINT8_MAX) { - uint8_t type = 0xC4; - uint8_t tmp = (uint8_t)_count; - - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: _count + 2]; - - [data addItem: &type]; - [data addItem: &tmp]; - } else if (_count <= UINT16_MAX) { - uint8_t type = 0xC5; - uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)_count); - - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: _count + 3]; - - [data addItem: &type]; - [data addItems: &tmp - count: sizeof(tmp)]; - } else if (_count <= UINT32_MAX) { - uint8_t type = 0xC6; - uint32_t tmp = OF_BSWAP32_IF_LE((uint32_t)_count); - - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: _count + 5]; - - [data addItem: &type]; - [data addItems: &tmp - count: sizeof(tmp)]; - } else - @throw [OFOutOfRangeException exception]; - - [data addItems: _items - count: _count]; - - return data; -} -@end Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -23,11 +23,11 @@ #import "OFDictionary.h" #import "OFDictionary_hashtable.h" #import "OFArray.h" #import "OFString.h" #import "OFXMLElement.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" #import "OFUndefinedKeyException.h" @@ -733,19 +733,19 @@ objc_autoreleasePoolPop(pool); return JSON; } -- (OFDataArray *)messagePackRepresentation +- (OFData *)messagePackRepresentation { - OFDataArray *data; + OFMutableData *data; size_t i, count; void *pool; OFEnumerator *keyEnumerator, *objectEnumerator; id key, object; - data = [OFDataArray dataArray]; + data = [OFMutableData data]; count = [self count]; if (count <= 15) { uint8_t tmp = 0x80 | ((uint8_t)count & 0xF); [data addItem: &tmp]; @@ -772,11 +772,11 @@ keyEnumerator = [self keyEnumerator]; objectEnumerator = [self objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); - OFDataArray *child; + OFData *child; i++; child = [key messagePackRepresentation]; [data addItems: [child items] @@ -788,11 +788,13 @@ objc_autoreleasePoolPop(pool2); } assert(i == count); + + [data makeImmutable]; objc_autoreleasePoolPop(pool); return data; } @end Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -29,11 +29,10 @@ #endif #import "OFFile.h" #import "OFString.h" #import "OFLocalization.h" -#import "OFDataArray.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" Index: src/OFHTTPClient.h ================================================================== --- src/OFHTTPClient.h +++ src/OFHTTPClient.h @@ -26,11 +26,10 @@ @class OFHTTPRequest; @class OFHTTPResponse; @class OFURL; @class OFTCPSocket; @class OFDictionary OF_GENERIC(KeyType, ObjectType); -@class OFDataArray; /*! * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A delegate for OFHTTPClient. Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -24,11 +24,11 @@ #import "OFHTTPResponse.h" #import "OFString.h" #import "OFURL.h" #import "OFTCPSocket.h" #import "OFDictionary.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" @@ -323,11 +323,11 @@ of_http_request_method_t method = [request method]; OFString *path; OFMutableString *requestString; OFString *user, *password; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; - OFDataArray *body = [request body]; + OFData *body = [request body]; OFTCPSocket *socket; OFHTTPClientResponse *response; OFString *line, *version, *redirect, *connectionHeader; bool keepAlive; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *serverHeaders; @@ -418,11 +418,11 @@ user = [URL user]; password = [URL password]; if (([user length] > 0 || [password length] > 0) && [headers objectForKey: @"Authorization"] == nil) { - OFDataArray *authorizationData = [OFDataArray dataArray]; + OFMutableData *authorizationData = [OFMutableData data]; OFString *authorization; [authorizationData addItems: [user UTF8String] count: [user UTF8StringLength]]; [authorizationData addItem: ":"]; Index: src/OFHTTPRequest.h ================================================================== --- src/OFHTTPRequest.h +++ src/OFHTTPRequest.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; @class OFDictionary OF_GENERIC(KeyType, ObjectType); -@class OFDataArray; +@class OFData; @class OFString; /*! @file */ /*! @@ -70,11 +70,11 @@ { OFURL *_URL; of_http_request_method_t _method; of_http_request_protocol_version_t _protocolVersion; OFDictionary OF_GENERIC(OFString *, OFString *) *_headers; - OFDataArray *_body; + OFData *_body; OFString *_remoteAddress; } /*! * The URL of the HTTP request. @@ -93,11 +93,11 @@ OFDictionary OF_GENERIC(OFString *, OFString *) *headers; /*! * The entity body of the HTTP request. */ -@property OF_NULLABLE_PROPERTY (nonatomic, retain) OFDataArray *body; +@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFData *body; /*! * The remote address from which the request originates. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *remoteAddress; Index: src/OFHTTPRequest.m ================================================================== --- src/OFHTTPRequest.m +++ src/OFHTTPRequest.m @@ -20,11 +20,11 @@ #import "OFHTTPRequest.h" #import "OFString.h" #import "OFURL.h" #import "OFDictionary.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFArray.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedVersionException.h" @@ -240,15 +240,14 @@ - (void)setBodyFromString: (OFString *)string encoding: (of_string_encoding_t)encoding { void *pool = objc_autoreleasePoolPush(); - OFDataArray *body = [OFDataArray dataArray]; - [body addItems: [string cStringWithEncoding: encoding] - count: [string cStringLengthWithEncoding: encoding]]; - [self setBody: body]; + [self setBody: [OFData + dataWithItems: [string cStringWithEncoding: encoding] + count: [string cStringLengthWithEncoding: encoding]]]; objc_autoreleasePoolPop(pool); } - (OFString *)description Index: src/OFHTTPResponse.m ================================================================== --- src/OFHTTPResponse.m +++ src/OFHTTPResponse.m @@ -18,11 +18,11 @@ #import "OFHTTPResponse.h" #import "OFString.h" #import "OFDictionary.h" #import "OFArray.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" @@ -209,20 +209,20 @@ - (OFString *)stringWithEncoding: (of_string_encoding_t)encoding { void *pool = objc_autoreleasePoolPush(); OFString *contentType, *contentLength, *ret; - OFDataArray *data; + OFData *data; if (encoding == OF_STRING_ENCODING_AUTODETECT && (contentType = [_headers objectForKey: @"Content-Type"]) != nil) encoding = encodingForContentType(contentType); if (encoding == OF_STRING_ENCODING_AUTODETECT) encoding = OF_STRING_ENCODING_UTF_8; - data = [self readDataArrayTillEndOfStream]; + data = [self readDataUntilEndOfStream]; if ((contentLength = [_headers objectForKey: @"Content-Length"]) != nil) if ([data count] != (size_t)[contentLength decimalValue]) @throw [OFTruncatedDataException exception]; Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -18,11 +18,11 @@ #include #include #import "OFHTTPServer.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFURL.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" @@ -333,11 +333,11 @@ of_http_request_method_t _method; OFString *_host, *_path; uint16_t _port; OFMutableDictionary *_headers; size_t _contentLength; - OFDataArray *_body; + OFMutableData *_body; } - initWithSocket: (OFTCPSocket *)socket server: (OFHTTPServer *)server; - (bool)socket: (OFTCPSocket *)socket @@ -498,11 +498,11 @@ if (contentLength > 0) { char *buffer; buffer = [self allocMemoryWithSize: BUFFER_SIZE]; - _body = [[OFDataArray alloc] init]; + _body = [[OFMutableData alloc] init]; [_socket asyncReadIntoBuffer: buffer length: BUFFER_SIZE target: self selector: @selector(socket: @@ -586,10 +586,12 @@ * now as the async read is the only thing referencing self and * the buffer is allocated on self, it is required once * Connection: keep-alive is implemented. */ [self freeMemory: buffer]; + + [_body makeImmutable]; @try { [self createResponse]; } @catch (OFWriteFailedException *e) { return false; Index: src/OFInflateStream.m ================================================================== --- src/OFInflateStream.m +++ src/OFInflateStream.m @@ -27,11 +27,10 @@ # import "OFInflateStream.h" #else # import "OFInflate64Stream.h" # define OFInflateStream OFInflate64Stream #endif -#import "OFDataArray.h" #import "OFInitializationFailedException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" Index: src/OFKernelEventObserver.h ================================================================== --- src/OFKernelEventObserver.h +++ src/OFKernelEventObserver.h @@ -23,11 +23,11 @@ @class OFMutableArray OF_GENERIC(ObjectType); @class OFDate; #ifdef OF_HAVE_THREADS @class OFMutex; #endif -@class OFDataArray; +@class OFMutableData; /*! * @protocol OFKernelEventObserverDelegate * OFKernelEventObserver.h ObjFW/OFKernelEventObserver.h * @@ -119,11 +119,11 @@ struct sockaddr_in _cancelAddr; #endif #ifdef OF_HAVE_THREADS OFMutex *_mutex; #endif - OFDataArray *_queueActions; + OFMutableData *_queueActions; OFMutableArray *_queueObjects; } /*! * The delegate for the OFKernelEventObserver. Index: src/OFKernelEventObserver.m ================================================================== --- src/OFKernelEventObserver.m +++ src/OFKernelEventObserver.m @@ -21,11 +21,11 @@ #include #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFArray.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFStream.h" #import "OFStream+Private.h" #ifndef OF_HAVE_PIPE # import "OFStreamSocket.h" #endif @@ -165,11 +165,11 @@ #ifdef OF_HAVE_THREADS _mutex = [[OFMutex alloc] init]; #endif - _queueActions = [[OFDataArray alloc] + _queueActions = [[OFMutableData alloc] initWithItemSize: sizeof(int)]; _queueObjects = [[OFMutableArray alloc] init]; } @catch (id e) { [self release]; @throw e; Index: src/OFKernelEventObserver_kqueue.h ================================================================== --- src/OFKernelEventObserver_kqueue.h +++ src/OFKernelEventObserver_kqueue.h @@ -16,15 +16,14 @@ #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN -@class OFDataArray; @class OFMutableArray OF_GENERIC(ObjectType); @interface OFKernelEventObserver_kqueue: OFKernelEventObserver { int _kernelQueue; } @end OF_ASSUME_NONNULL_END Index: src/OFKernelEventObserver_kqueue.m ================================================================== --- src/OFKernelEventObserver_kqueue.m +++ src/OFKernelEventObserver_kqueue.m @@ -30,11 +30,10 @@ #include #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver_kqueue.h" -#import "OFDataArray.h" #import "OFArray.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif Index: src/OFKernelEventObserver_poll.h ================================================================== --- src/OFKernelEventObserver_poll.h +++ src/OFKernelEventObserver_poll.h @@ -16,16 +16,16 @@ #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN -@class OFDataArray; +@class OFMutableData; @interface OFKernelEventObserver_poll: OFKernelEventObserver { - OFDataArray *_FDs; + OFMutableData *_FDs; int _maxFD; id __unsafe_unretained *_FDToObject; } @end OF_ASSUME_NONNULL_END Index: src/OFKernelEventObserver_poll.m ================================================================== --- src/OFKernelEventObserver_poll.m +++ src/OFKernelEventObserver_poll.m @@ -26,11 +26,11 @@ #endif #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver_poll.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #import "socket_helpers.h" @@ -46,11 +46,11 @@ self = [super init]; @try { struct pollfd p = { _cancelFD[0], POLLIN, 0 }; - _FDs = [[OFDataArray alloc] initWithItemSize: + _FDs = [[OFMutableData alloc] initWithItemSize: sizeof(struct pollfd)]; [_FDs addItem: &p]; _maxFD = _cancelFD[0]; _FDToObject = [self allocMemoryWithSize: sizeof(id) Index: src/OFMessagePackExtension.h ================================================================== --- src/OFMessagePackExtension.h +++ src/OFMessagePackExtension.h @@ -17,11 +17,11 @@ #import "OFObject.h" #import "OFMessagePackRepresentation.h" OF_ASSUME_NONNULL_BEGIN -@class OFDataArray; +@class OFData; /*! * @class OFMessagePackExtension \ * OFMessagePackExtension.h ObjFW/OFMessagePackExtension.h * @@ -29,11 +29,11 @@ */ @interface OFMessagePackExtension: OFObject { int8_t _type; - OFDataArray *_data; + OFData *_data; } /*! * The MessagePack extension type. */ @@ -40,11 +40,11 @@ @property (readonly, nonatomic) int8_t type; /*! * @return The data of the extension. */ -@property (readonly, nonatomic) OFDataArray *data; +@property (readonly, nonatomic) OFData *data; /*! * @brief Creates a new OFMessagePackRepresentation with the specified type and * data. * @@ -51,11 +51,11 @@ * @param type The MessagePack extension type * @param data The data for the extension * @return A new, autoreleased OFMessagePackRepresentation */ + (instancetype)extensionWithType: (int8_t)type - data: (OFDataArray *)data; + data: (OFData *)data; - init OF_UNAVAILABLE; /*! * @brief Initializes an already allocated OFMessagePackRepresentation with the @@ -64,9 +64,9 @@ * @param type The MessagePack extension type * @param data The data for the extension * @return An initialized OFMessagePackRepresentation */ - initWithType: (int8_t)type - data: (OFDataArray *)data OF_DESIGNATED_INITIALIZER; + data: (OFData *)data OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/OFMessagePackExtension.m ================================================================== --- src/OFMessagePackExtension.m +++ src/OFMessagePackExtension.m @@ -15,20 +15,20 @@ */ #include "config.h" #import "OFMessagePackExtension.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFString.h" #import "OFInvalidArgumentException.h" @implementation OFMessagePackExtension @synthesize type = _type, data = _data; + (instancetype)extensionWithType: (int8_t)type - data: (OFDataArray *)data + data: (OFData *)data { return [[[self alloc] initWithType: type data: data] autorelease]; } @@ -36,20 +36,20 @@ { OF_INVALID_INIT_METHOD } - initWithType: (int8_t)type - data: (OFDataArray *)data + data: (OFData *)data { self = [super init]; @try { if (data == nil || [data itemSize] != 1) @throw [OFInvalidArgumentException exception]; _type = type; - _data = [data retain]; + _data = [data copy]; } @catch (id e) { [self release]; @throw e; } @@ -61,55 +61,55 @@ [_data release]; [super dealloc]; } -- (OFDataArray *)messagePackRepresentation +- (OFData *)messagePackRepresentation { - OFDataArray *ret; + OFMutableData *ret; uint8_t prefix; size_t count = [_data count]; if (count == 1) { - ret = [OFDataArray dataArrayWithCapacity: 3]; + ret = [OFMutableData dataWithCapacity: 3]; prefix = 0xD4; [ret addItem: &prefix]; [ret addItem: &_type]; } else if (count == 2) { - ret = [OFDataArray dataArrayWithCapacity: 4]; + ret = [OFMutableData dataWithCapacity: 4]; prefix = 0xD5; [ret addItem: &prefix]; [ret addItem: &_type]; } else if (count == 4) { - ret = [OFDataArray dataArrayWithCapacity: 6]; + ret = [OFMutableData dataWithCapacity: 6]; prefix = 0xD6; [ret addItem: &prefix]; [ret addItem: &_type]; } else if (count == 8) { - ret = [OFDataArray dataArrayWithCapacity: 10]; + ret = [OFMutableData dataWithCapacity: 10]; prefix = 0xD7; [ret addItem: &prefix]; [ret addItem: &_type]; } else if (count == 16) { - ret = [OFDataArray dataArrayWithCapacity: 18]; + ret = [OFMutableData dataWithCapacity: 18]; prefix = 0xD8; [ret addItem: &prefix]; [ret addItem: &_type]; } else if (count < 0x100) { uint8_t length; - ret = [OFDataArray dataArrayWithCapacity: count + 3]; + ret = [OFMutableData dataWithCapacity: count + 3]; prefix = 0xC7; [ret addItem: &prefix]; length = (uint8_t)count; @@ -117,11 +117,11 @@ [ret addItem: &_type]; } else if (count < 0x10000) { uint16_t length; - ret = [OFDataArray dataArrayWithCapacity: count + 4]; + ret = [OFMutableData dataWithCapacity: count + 4]; prefix = 0xC8; [ret addItem: &prefix]; length = OF_BSWAP16_IF_LE((uint16_t)count); @@ -130,11 +130,11 @@ [ret addItem: &_type]; } else { uint32_t length; - ret = [OFDataArray dataArrayWithCapacity: count + 6]; + ret = [OFMutableData dataWithCapacity: count + 6]; prefix = 0xC9; [ret addItem: &prefix]; length = OF_BSWAP32_IF_LE((uint32_t)count); @@ -144,10 +144,12 @@ [ret addItem: &_type]; } [ret addItems: [_data items] count: [_data count]]; + + [ret makeImmutable]; return ret; } - (OFString *)description @@ -185,19 +187,8 @@ return hash; } - copy { - OFMessagePackExtension *ret; - OFDataArray *data; - - data = [_data copy]; - @try { - ret = [[OFMessagePackExtension alloc] initWithType: _type - data: data]; - } @finally { - [data release]; - } - - return ret; + return [self retain]; } @end Index: src/OFMessagePackRepresentation.h ================================================================== --- src/OFMessagePackRepresentation.h +++ src/OFMessagePackRepresentation.h @@ -16,11 +16,11 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -@class OFDataArray; +@class OFData; /*! * @protocol OFMessagePackRepresentation * OFMessagePackRepresentation.h ObjFW/OFMessagePackRepresentation.h * @@ -27,14 +27,13 @@ * @brief A protocol implemented by classes that support encoding to a * MessagePack representation. */ @protocol OFMessagePackRepresentation /*! - * @brief Returns the MessagePack representation of the object as an - * OFDataArray. + * @brief Returns the MessagePack representation of the object as OFData. * - * @return The MessagePack representation of the object as an OFDataArray. + * @return The MessagePack representation of the object as OFData. */ -- (OFDataArray *)messagePackRepresentation; +- (OFData *)messagePackRepresentation; @end OF_ASSUME_NONNULL_END Index: src/OFMutableArray_adjacent.h ================================================================== --- src/OFMutableArray_adjacent.h +++ src/OFMutableArray_adjacent.h @@ -16,15 +16,15 @@ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN -@class OFDataArray; +@class OFMutableData; @interface OFMutableArray_adjacent: OFMutableArray { - OFDataArray *_array; + OFMutableData *_array; unsigned long _mutations; } @end OF_ASSUME_NONNULL_END Index: src/OFMutableArray_adjacent.m ================================================================== --- src/OFMutableArray_adjacent.m +++ src/OFMutableArray_adjacent.m @@ -18,11 +18,11 @@ #include #import "OFMutableArray_adjacent.h" #import "OFArray_adjacent.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" @@ -36,12 +36,12 @@ - initWithCapacity: (size_t)capacity { self = [super init]; @try { - _array = [[OFDataArray alloc] initWithItemSize: sizeof(id) - capacity: capacity]; + _array = [[OFMutableData alloc] initWithItemSize: sizeof(id) + capacity: capacity]; } @catch (id e) { [self release]; @throw e; } ADDED src/OFMutableData.h Index: src/OFMutableData.h ================================================================== --- src/OFMutableData.h +++ src/OFMutableData.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFData.h" + +OF_ASSUME_NONNULL_BEGIN + +@class OFString; +@class OFURL; + +/*! + * @class OFMutableData OFMutableData.h ObjFW/OFMutableData.h + * + * @brief A class for storing and manipulating arbitrary data in an array. + */ +@interface OFMutableData: OFData +{ + size_t _capacity; +} + +/*! + * @brief Creates a new OFMutableData with an item size of 1. + * + * @return A new autoreleased OFMutableData + */ ++ (instancetype)data; + +/*! + * @brief Creates a new OFMutableData whose items all have the same specified + * size. + * + * @param itemSize The size of a single element in the OFMutableData + * @return A new autoreleased OFMutableData + */ ++ (instancetype)dataWithItemSize: (size_t)itemSize; + +/*! + * @brief Creates a new OFMutableData with enough memory to hold the specified + * number of items which all have an item size of 1. + * + * @param capacity The initial capacity for the OFMutableData + * @return A new autoreleased OFMutableData + */ ++ (instancetype)dataWithCapacity: (size_t)capacity; + +/*! + * @brief Creates a new OFMutableData with enough memory to hold the specified + * number of items which all have the same specified size. + * + * @param itemSize The size of a single element in the OFMutableData + * @param capacity The initial capacity for the OFMutableData + * @return A new autoreleased OFMutableData + */ ++ (instancetype)dataWithItemSize: (size_t)itemSize + capacity: (size_t)capacity; + ++ (instancetype)dataWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; ++ (instancetype)dataWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated OFMutableData with an item size of 1. + * + * @return An initialized OFMutableData + */ +- init; + +/*! + * @brief Initializes an already allocated OFMutableData whose items all have + * the same size. + * + * @param itemSize The size of a single element in the OFMutableData + * @return An initialized OFMutableData + */ +- initWithItemSize: (size_t)itemSize; + +/*! + * @brief Initializes an already allocated OFMutableData with enough memory to + * hold the the specified number of items which all have an item size of + * 1. + * + * @param capacity The initial capacity for the OFMutableData + * @return An initialized OFMutableData + */ +- initWithCapacity: (size_t)capacity; + +/*! + * @brief Initializes an already allocated OFMutableData with enough memory to + * hold the the specified number of items which all have the same + * specified size. + * + * @param itemSize The size of a single element in the OFMutableData + * @param capacity The initial capacity for the OFMutableData + * @return An initialized OFMutableData + */ +- initWithItemSize: (size_t)itemSize + capacity: (size_t)capacity; + +- initWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; +- initWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; + +/*! + * @brief Adds an item to the OFMutableData. + * + * @param item A pointer to an arbitrary item + */ +- (void)addItem: (const void *)item; + +/*! + * @brief Adds an item to the OFMutableData at the specified index. + * + * @param item A pointer to an arbitrary item + * @param index The index where the item should be added + */ +- (void)insertItem: (const void *)item + atIndex: (size_t)index; + +/*! + * @brief Adds items from a C array to the OFMutableData. + * + * @param items A C array containing the items to add + * @param count The number of items to add + */ +- (void)addItems: (const void *)items + count: (size_t)count; + +/*! + * @brief Adds items from a C array to the OFMutableData at the specified index. + * + * @param items A C array containing the items to add + * @param index The index where the items should be added + * @param count The number of items to add + */ +- (void)insertItems: (const void *)items + atIndex: (size_t)index + count: (size_t)count; + +/*! + * @brief Removes the item at the specified index. + * + * @param index The index of the item to remove + */ +- (void)removeItemAtIndex: (size_t)index; + +/*! + * @brief Removes the specified amount of items at the specified index. + * + * @param range The range of items to remove + */ +- (void)removeItemsInRange: (of_range_t)range; + +/*! + * @brief Removes the last item. + */ +- (void)removeLastItem; + +/*! + * @brief Removes all items. + */ +- (void)removeAllItems; + +/*! + * @brief Converts the mutable URL to an immutable URL. + */ +- (void)makeImmutable; +@end + +@interface OFMutableData (MutableRetrieving) +/*! + * @brief Returns all items of the OFMutableData as a C array. + * + * @warning The pointer is only valid until the OFMutableData is changed! + * + * Modifying the returned array directly is allowed and will change the contents + * of the data array. + * + * @return All elements of the OFMutableData as a C array + */ +- (void *)items OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns a specific item of the OFMutableData. + * + * Modifying the returned item directly is allowed and will change the contents + * of the data array. + * + * @param index The number of the item to return + * @return The specified item of the OFMutableData + */ +- (void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns the first item of the OFMutableData. + * + * Modifying the returned item directly is allowed and will change the contents + * of the data array. + * + * @return The first item of the OFMutableData or NULL + */ +- (nullable void *)firstItem OF_RETURNS_INNER_POINTER; + +/*! + * @brief Returns the last item of the OFMutableData. + * + * Modifying the returned item directly is allowed and will change the contents + * of the data array. + * + * @return The last item of the OFMutableData or NULL + */ +- (nullable void *)lastItem OF_RETURNS_INNER_POINTER; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFMutableData.m Index: src/OFMutableData.m ================================================================== --- src/OFMutableData.m +++ src/OFMutableData.m @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 +#include +#include + +#import "OFMutableData.h" +#import "OFData+Private.h" +#import "OFString.h" + +#import "OFInvalidArgumentException.h" +#import "OFOutOfMemoryException.h" +#import "OFOutOfRangeException.h" + +@implementation OFMutableData ++ (instancetype)data +{ + return [[[self alloc] init] autorelease]; +} + ++ (instancetype)dataWithItemSize: (size_t)itemSize +{ + return [[[self alloc] initWithItemSize: itemSize] autorelease]; +} + ++ (instancetype)dataWithCapacity: (size_t)capacity +{ + return [[[self alloc] initWithCapacity: capacity] autorelease]; +} + ++ (instancetype)dataWithItemSize: (size_t)itemSize + capacity: (size_t)capacity +{ + return [[[self alloc] initWithItemSize: itemSize + capacity: capacity] autorelease]; +} + ++ (instancetype)dataWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + OF_UNRECOGNIZED_SELECTOR +} + ++ (instancetype)dataWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + OF_UNRECOGNIZED_SELECTOR +} + +- init +{ + self = [super of_init]; + + _itemSize = 1; + + return self; +} + +- initWithItemSize: (size_t)itemSize +{ + self = [super of_init]; + + @try { + if (itemSize == 0) + @throw [OFInvalidArgumentException exception]; + + _itemSize = itemSize; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithCapacity: (size_t)capacity +{ + return [self initWithItemSize: 1 + capacity: capacity]; +} + +- initWithItemSize: (size_t)itemSize + capacity: (size_t)capacity +{ + self = [super of_init]; + + @try { + if (itemSize == 0) + @throw [OFInvalidArgumentException exception]; + + _items = [self allocMemoryWithSize: itemSize + count: capacity]; + + _itemSize = itemSize; + _capacity = capacity; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithItems: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count +{ + self = [super initWithItems: items + itemSize: itemSize + count: count]; + + _capacity = _count; + + return self; +} + +- initWithItemsNoCopy: (const void *)items + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + OF_INVALID_INIT_METHOD +} + +- initWithItemsNoCopy: (const void *)items + itemSize: (size_t)itemSize + count: (size_t)count + freeWhenDone: (bool)freeWhenDone +{ + OF_INVALID_INIT_METHOD +} + +- initWithStringRepresentation: (OFString *)string +{ + self = [super initWithStringRepresentation: string]; + + _capacity = _count; + + return self; +} + +- (void)addItem: (const void *)item +{ + if (SIZE_MAX - _count < 1) + @throw [OFOutOfRangeException exception]; + + if (_count + 1 > _capacity) { + _items = [self resizeMemory: _items + size: _itemSize + count: _count + 1]; + _capacity = _count + 1; + } + + memcpy(_items + _count * _itemSize, item, _itemSize); + + _count++; +} + +- (void)insertItem: (const void *)item + atIndex: (size_t)index +{ + [self insertItems: item + atIndex: index + count: 1]; +} + +- (void)addItems: (const void *)items + count: (size_t)count +{ + if (count > SIZE_MAX - _count) + @throw [OFOutOfRangeException exception]; + + if (_count + count > _capacity) { + _items = [self resizeMemory: _items + size: _itemSize + count: _count + count]; + _capacity = _count + count; + } + + memcpy(_items + _count * _itemSize, items, count * _itemSize); + _count += count; +} + +- (void)insertItems: (const void *)items + atIndex: (size_t)index + count: (size_t)count +{ + if (count > SIZE_MAX - _count || index > _count) + @throw [OFOutOfRangeException exception]; + + if (_count + count > _capacity) { + _items = [self resizeMemory: _items + size: _itemSize + count: _count + count]; + _capacity = _count + count; + } + + memmove(_items + (index + count) * _itemSize, + _items + index * _itemSize, (_count - index) * _itemSize); + memcpy(_items + index * _itemSize, items, count * _itemSize); + + _count += count; +} + +- (void)removeItemAtIndex: (size_t)index +{ + [self removeItemsInRange: of_range(index, 1)]; +} + +- (void)removeItemsInRange: (of_range_t)range +{ + if (range.length > SIZE_MAX - range.location || + range.location + range.length > _count) + @throw [OFOutOfRangeException exception]; + + memmove(_items + range.location * _itemSize, + _items + (range.location + range.length) * _itemSize, + (_count - range.location - range.length) * _itemSize); + + _count -= range.length; + @try { + _items = [self resizeMemory: _items + size: _itemSize + count: _count]; + _capacity = _count; + } @catch (OFOutOfMemoryException *e) { + /* We don't really care, as we only made it smaller */ + } +} + +- (void)removeLastItem +{ + if (_count == 0) + return; + + _count--; + @try { + _items = [self resizeMemory: _items + size: _itemSize + count: _count]; + _capacity = _count; + } @catch (OFOutOfMemoryException *e) { + /* We don't care, as we only made it smaller */ + } +} + +- (void)removeAllItems +{ + [self freeMemory: _items]; + + _items = NULL; + _count = 0; + _capacity = 0; +} + +- copy +{ + return [[OFData alloc] initWithItems: _items + itemSize: _itemSize + count: _count]; +} + +- (void)makeImmutable +{ + object_setClass(self, [OFData class]); +} +@end Index: src/OFNull.m ================================================================== --- src/OFNull.m +++ src/OFNull.m @@ -17,11 +17,11 @@ #include "config.h" #import "OFNull.h" #import "OFString.h" #import "OFXMLElement.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFInvalidArgumentException.h" @interface OFNull () - (OFString *)of_JSONRepresentationWithOptions: (int)options @@ -99,19 +99,16 @@ depth: (size_t)depth { return @"null"; } -- (OFDataArray *)messagePackRepresentation +- (OFData *)messagePackRepresentation { - OFDataArray *data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 1]; uint8_t type = 0xC0; - [data addItem: &type]; - - return data; + return [OFData dataWithItems: &type + count: 1]; } - autorelease { return self; Index: src/OFNumber.m ================================================================== --- src/OFNumber.m +++ src/OFNumber.m @@ -21,11 +21,11 @@ #import "OFNumber.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFXMLAttribute.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" @@ -1046,42 +1046,35 @@ } return [self description]; } -- (OFDataArray *)messagePackRepresentation +- (OFData *)messagePackRepresentation { - OFDataArray *data; + OFMutableData *data; if (_type == OF_NUMBER_TYPE_BOOL) { - uint8_t type; - - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 1]; - - if (_value.bool_) - type = 0xC3; - else - type = 0xC2; - - [data addItem: &type]; + uint8_t type = (_value.bool_ ? 0xC3 : 0xC2); + + data = [OFMutableData dataWithItems: &type + count: 1]; } else if (_type == OF_NUMBER_TYPE_FLOAT) { uint8_t type = 0xCA; float tmp = OF_BSWAP_FLOAT_IF_LE(_value.float_); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 5]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (_type == OF_NUMBER_TYPE_DOUBLE) { uint8_t type = 0xCB; double tmp = OF_BSWAP_DOUBLE_IF_LE(_value.double_); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 9]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (_type & OF_NUMBER_TYPE_SIGNED) { @@ -1088,49 +1081,47 @@ intmax_t value = [self intMaxValue]; if (value >= -32 && value < 0) { uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 1]; - - [data addItem: &tmp]; + data = [OFMutableData dataWithItems: &tmp + count: 1]; } else if (value >= INT8_MIN && value <= INT8_MAX) { uint8_t type = 0xD0; int8_t tmp = (int8_t)value; - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 2]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (value >= INT16_MIN && value <= INT16_MAX) { uint8_t type = 0xD1; int16_t tmp = OF_BSWAP16_IF_LE((int16_t)value); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 3]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value >= INT32_MIN && value <= INT32_MAX) { uint8_t type = 0xD2; int32_t tmp = OF_BSWAP32_IF_LE((int32_t)value); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 5]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value >= INT64_MIN && value <= INT64_MAX) { uint8_t type = 0xD3; int64_t tmp = OF_BSWAP64_IF_LE((int64_t)value); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 9]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @@ -1139,55 +1130,55 @@ uintmax_t value = [self uIntMaxValue]; if (value <= 127) { uint8_t tmp = ((uint8_t)value & 0x7F); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 1]; - - [data addItem: &tmp]; + data = [OFMutableData dataWithItems: &tmp + count: 1]; } else if (value <= UINT8_MAX) { uint8_t type = 0xCC; uint8_t tmp = (uint8_t)value; - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 2]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (value <= UINT16_MAX) { uint8_t type = 0xCD; uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)value); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 3]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value <= UINT32_MAX) { uint8_t type = 0xCE; uint32_t tmp = OF_BSWAP32_IF_LE((uint32_t)value); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 5]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value <= UINT64_MAX) { uint8_t type = 0xCF; uint64_t tmp = OF_BSWAP64_IF_LE((uint64_t)value); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: 9]; + data = [OFMutableData dataWithItemSize: 1 + capacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; } + + [data makeImmutable]; return data; } @end Index: src/OFProcess.m ================================================================== --- src/OFProcess.m +++ src/OFProcess.m @@ -32,11 +32,11 @@ #import "OFProcess.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFLocalization.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" @@ -399,20 +399,20 @@ return envp; } #else - (char16_t *)of_environmentForDictionary: (OFDictionary *)environment { - OFDataArray *env; + OFMutableData *env; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; const char16_t equal = '='; const char16_t zero[2] = { 0, 0 }; if (environment == nil) return NULL; - env = [OFDataArray dataArrayWithItemSize: sizeof(char16_t)]; + env = [OFMutableData dataWithItemSize: sizeof(char16_t)]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { Index: src/OFStdIOStream_Win32Console.m ================================================================== --- src/OFStdIOStream_Win32Console.m +++ src/OFStdIOStream_Win32Console.m @@ -46,11 +46,11 @@ #include #import "OFStdIOStream_Win32Console.h" #import "OFStdIOStream+Private.h" #import "OFString.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" @@ -114,11 +114,11 @@ UTF16 = [self allocMemoryWithSize: sizeof(char16_t) count: length]; @try { DWORD UTF16Len; - OFDataArray *rest = nil; + OFMutableData *rest = nil; size_t i = 0; if (!ReadConsoleW(_handle, UTF16, (DWORD)length, &UTF16Len, NULL)) @throw [OFReadFailedException @@ -139,11 +139,11 @@ if (UTF8Len <= length) { memcpy(buffer, UTF8, UTF8Len); j += UTF8Len; } else { if (rest == nil) - rest = [OFDataArray dataArray]; + rest = [OFMutableData data]; [rest addItems: UTF8 count: UTF8Len]; } @@ -197,11 +197,11 @@ if (j + UTF8Len <= length) { memcpy(buffer + j, UTF8, UTF8Len); j += UTF8Len; } else { if (rest == nil) - rest = [OFDataArray dataArray]; + rest = [OFMutableData data]; [rest addItems: UTF8 count: UTF8Len]; } } Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -32,11 +32,11 @@ OF_ASSUME_NONNULL_BEGIN /*! @file */ @class OFStream; -@class OFDataArray; +@class OFData; @class OFException; #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_BLOCKS) /*! * @brief A block which is called when data was read from the stream. @@ -521,41 +521,41 @@ - (size_t)readLittleEndianDoublesIntoBuffer: (double *)buffer count: (size_t)count; /*! * @brief Reads the specified number of items with an item size of 1 from the - * stream and returns them in an OFDataArray. + * stream and returns them as OFData. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @param count The number of items to read - * @return An OFDataArray with count items. + * @return OFData with count items. */ -- (OFDataArray *)readDataArrayWithCount: (size_t)count; +- (OFData *)readDataWithCount: (size_t)count; /*! * @brief Reads the specified number of items with the specified item size from - * the stream and returns them in an OFDataArray. + * the stream and returns them as OFData. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @param itemSize The size of each item * @param count The number of items to read - * @return An OFDataArray with count items. + * @return OFData with count items. */ -- (OFDataArray *)readDataArrayWithItemSize: (size_t)itemSize - count: (size_t)count; +- (OFData *)readDataWithItemSize: (size_t)itemSize + count: (size_t)count; /*! - * @brief Returns an OFDataArray with all the remaining data of the stream. + * @brief Returns OFData with all the remaining data of the stream. * - * @return An OFDataArray with an item size of 1 with all the data of the - * stream until the end of the stream is reached. + * @return OFData with an item size of 1 with all the data of the stream until + * the end of the stream is reached. */ -- (OFDataArray *)readDataArrayTillEndOfStream; +- (OFData *)readDataUntilEndOfStream; /*! * @brief Reads a string with the specified length from the stream. * * If `\0` appears in the stream, the string will be truncated at the `\0` and @@ -973,16 +973,16 @@ */ - (size_t)writeLittleEndianDoubles: (const double *)buffer count: (size_t)count; /*! - * @brief Writes from an OFDataArray into the stream. + * @brief Writes OFData into the stream. * - * @param dataArray The OFDataArray to write into the stream + * @param data The OFData to write into the stream * @return The number of bytes written */ -- (size_t)writeDataArray: (OFDataArray *)dataArray; +- (size_t)writeData: (OFData *)data; /*! * @brief Writes a string into the stream, without the trailing zero. * * @param string The string from which the data is written to the stream Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -36,18 +36,19 @@ #endif #import "OFStream.h" #import "OFStream+Private.h" #import "OFString.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFSystemInfo.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" +#import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFSetOptionFailedException.h" #import "OFTruncatedDataException.h" #import "of_asprintf.h" @@ -552,63 +553,67 @@ #endif return size; } -- (OFDataArray *)readDataArrayWithCount: (size_t)count -{ - return [self readDataArrayWithItemSize: 1 - count: count]; -} - -- (OFDataArray *)readDataArrayWithItemSize: (size_t)itemSize - count: (size_t)count -{ - OFDataArray *dataArray; - char *tmp; - - dataArray = [OFDataArray dataArrayWithItemSize: itemSize]; - tmp = [self allocMemoryWithSize: itemSize - count: count]; - - @try { - [self readIntoBuffer: tmp +- (OFData *)readDataWithCount: (size_t)count +{ + return [self readDataWithItemSize: 1 + count: count]; +} + +- (OFData *)readDataWithItemSize: (size_t)itemSize + count: (size_t)count +{ + OFData *ret; + char *buffer; + + if OF_UNLIKELY (count > SIZE_MAX / itemSize) + @throw [OFOutOfRangeException exception]; + + if OF_UNLIKELY ((buffer = malloc(count * itemSize)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: count * itemSize]; + + @try { + [self readIntoBuffer: buffer exactLength: count * itemSize]; - [dataArray addItems: tmp - count: count]; - } @finally { - [self freeMemory: tmp]; - } - - return dataArray; -} - -- (OFDataArray *)readDataArrayTillEndOfStream -{ - OFDataArray *dataArray; - size_t pageSize; - char *buffer; - - dataArray = [OFDataArray dataArray]; - pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; + ret = [OFData dataWithItemsNoCopy: buffer + itemSize: itemSize + count: count + freeWhenDone: true]; + } @catch (id e) { + free(buffer); + @throw e; + } + + return ret; +} + +- (OFData *)readDataUntilEndOfStream +{ + OFMutableData *data = [OFMutableData data]; + size_t pageSize = [OFSystemInfo pageSize]; + char *buffer = [self allocMemoryWithSize: pageSize]; @try { while (![self isAtEndOfStream]) { size_t length; length = [self readIntoBuffer: buffer length: pageSize]; - [dataArray addItems: buffer - count: length]; + [data addItems: buffer + count: length]; } } @finally { [self freeMemory: buffer]; } - return dataArray; + [data makeImmutable]; + + return data; } - (OFString *)readStringWithLength: (size_t)length { return [self readStringWithLength: length @@ -1441,15 +1446,15 @@ #endif return size; } -- (size_t)writeDataArray: (OFDataArray *)dataArray +- (size_t)writeData: (OFData *)data { - size_t length = [dataArray count] * [dataArray itemSize]; + size_t length = [data count] * [data itemSize]; - [self writeBuffer: [dataArray items] + [self writeBuffer: [data items] length: length]; return length; } Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -32,11 +32,11 @@ #import "OFString.h" #import "OFString_UTF8.h" #import "OFString_UTF8+Private.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFLocalization.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif @@ -1007,43 +1007,40 @@ } - initWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding { - void *pool; - OFString *scheme; -# ifdef OF_HAVE_FILES - Class c = [self class]; -# endif - - [self release]; - - pool = objc_autoreleasePoolPush(); - - scheme = [URL scheme]; + void *pool = objc_autoreleasePoolPush(); + OFString *scheme = [URL scheme]; # ifdef OF_HAVE_FILES if ([scheme isEqual: @"file"]) { if (encoding == OF_STRING_ENCODING_AUTODETECT) encoding = OF_STRING_ENCODING_UTF_8; - self = [[c alloc] initWithContentsOfFile: [URL path] - encoding: encoding]; + self = [self initWithContentsOfFile: [URL path] + encoding: encoding]; } else # endif # ifdef OF_HAVE_SOCKETS if ([scheme isEqual: @"http"] || [scheme isEqual: @"https"]) { + bool mutable = [self isKindOfClass: [OFMutableString class]]; OFHTTPClient *client = [OFHTTPClient client]; OFHTTPRequest *request = [OFHTTPRequest requestWithURL: URL]; OFHTTPResponse *response = [client performRequest: request]; if ([response statusCode] != 200) @throw [OFHTTPRequestFailedException exceptionWithRequest: request response: response]; - self = [[response string] retain]; + [self release]; + + if (mutable) + self = [[response string] mutableCopy]; + else + self = [[response string] copy]; } else # endif @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; objc_autoreleasePoolPop(pool); @@ -1720,49 +1717,49 @@ [JSON makeImmutable]; return JSON; } -- (OFDataArray *)messagePackRepresentation +- (OFData *)messagePackRepresentation { - OFDataArray *data; + OFMutableData *data; size_t length; length = [self UTF8StringLength]; if (length <= 31) { uint8_t tmp = 0xA0 | ((uint8_t)length & 0x1F); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: length + 1]; + data = [OFMutableData dataWithItemSize: 1 + capacity: length + 1]; [data addItem: &tmp]; } else if (length <= UINT8_MAX) { uint8_t type = 0xD9; uint8_t tmp = (uint8_t)length; - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: length + 2]; + data = [OFMutableData dataWithItemSize: 1 + capacity: length + 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (length <= UINT16_MAX) { uint8_t type = 0xDA; uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)length); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: length + 3]; + data = [OFMutableData dataWithItemSize: 1 + capacity: length + 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (length <= UINT32_MAX) { uint8_t type = 0xDB; uint32_t tmp = OF_BSWAP32_IF_LE((uint32_t)length); - data = [OFDataArray dataArrayWithItemSize: 1 - capacity: length + 5]; + data = [OFMutableData dataWithItemSize: 1 + capacity: length + 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else Index: src/OFTCPSocket+SOCKS5.m ================================================================== --- src/OFTCPSocket+SOCKS5.m +++ src/OFTCPSocket+SOCKS5.m @@ -17,11 +17,11 @@ #include "config.h" #include #import "OFTCPSocket+SOCKS5.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFConnectionFailedException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" @@ -77,11 +77,11 @@ port: (uint16_t)port { char request[] = { 5, 1, 0, 3 }; char reply[256]; void *pool; - OFDataArray *connectRequest; + OFMutableData *connectRequest; if ([host UTF8StringLength] > 255) @throw [OFOutOfRangeException exception]; /* 5 1 0 -> no authentication */ @@ -98,11 +98,11 @@ errNo: EPROTONOSUPPORT]; } /* CONNECT request */ pool = objc_autoreleasePoolPush(); - connectRequest = [OFDataArray dataArray]; + connectRequest = [OFMutableData data]; [connectRequest addItems: request count: 4]; request[0] = [host UTF8StringLength]; Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -24,11 +24,11 @@ #import "OFXMLElement.h" #import "OFXMLNode+Private.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFXMLAttribute.h" #import "OFXMLCharacters.h" #import "OFXMLCDATA.h" #import "OFXMLParser.h" #import "OFXMLElementBuilder.h" @@ -564,11 +564,11 @@ objc_autoreleasePoolPop(pool2); } /* Children */ if (_children != nil) { - OFDataArray *tmp = [OFDataArray dataArray]; + OFMutableData *tmp = [OFMutableData data]; bool indent; if (indentation > 0) { indent = true; Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -19,11 +19,11 @@ #import "OFXMLAttribute.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); -@class OFDataArray; +@class OFMutableData; @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFStream; @class OFXMLParser; @@ -154,11 +154,11 @@ OF_XMLPARSER_IN_DOCTYPE, OF_XMLPARSER_NUM_STATES } _state; size_t _i, _last; const char *_data; - OFDataArray *_buffer; + OFMutableData *_buffer; OFString *_name, *_prefix; OFMutableArray OF_GENERIC(OFMutableDictionary OF_GENERIC(OFString *, OFString *) *) *_namespaces; OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes; Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -20,11 +20,11 @@ #import "OFXMLParser.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFBigDataArray.h" +#import "OFData.h" #import "OFXMLAttribute.h" #import "OFStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif @@ -39,11 +39,11 @@ typedef void (*state_function_t)(id, SEL); static SEL selectors[OF_XMLPARSER_NUM_STATES]; static state_function_t lookupTable[OF_XMLPARSER_NUM_STATES]; static OF_INLINE void -appendToBuffer(OFDataArray *buffer, const char *string, +appendToBuffer(OFMutableData *buffer, const char *string, of_string_encoding_t encoding, size_t length) { if (OF_LIKELY(encoding == OF_STRING_ENCODING_UTF_8)) [buffer addItems: string count: length]; @@ -57,11 +57,11 @@ objc_autoreleasePoolPop(pool); } } static OFString * -transformString(OFXMLParser *parser, OFDataArray *buffer, size_t cut, +transformString(OFXMLParser *parser, OFMutableData *buffer, size_t cut, bool unescape) { char *items = [buffer items]; size_t length = [buffer count] - cut; bool hasEntities = false; @@ -186,11 +186,11 @@ @try { void *pool; OFMutableDictionary *dict; - _buffer = [[OFBigDataArray alloc] init]; + _buffer = [[OFMutableData alloc] init]; _previous = [[OFMutableArray alloc] init]; _namespaces = [[OFMutableArray alloc] init]; _attributes = [[OFMutableArray alloc] init]; pool = objc_autoreleasePoolPush(); Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -19,11 +19,11 @@ #include #import "OFZIPArchive.h" #import "OFZIPArchiveEntry.h" #import "OFZIPArchiveEntry+Private.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFSeekableStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" @@ -61,11 +61,11 @@ uint16_t _minVersionNeeded, _generalPurposeBitFlag, _compressionMethod; uint16_t _lastModifiedFileTime, _lastModifiedFileDate; uint32_t _CRC32; uint64_t _compressedSize, _uncompressedSize; OFString *_fileName; - OFDataArray *_extraField; + OFData *_extraField; } - initWithStream: (OFStream *)stream; - (bool)matchesEntry: (OFZIPArchiveEntry *)entry; @end @@ -83,11 +83,11 @@ - initWithStream: (OFStream *)path localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader; @end uint32_t -of_zip_archive_read_field32(uint8_t **data, uint16_t *size) +of_zip_archive_read_field32(const uint8_t **data, uint16_t *size) { uint32_t field = 0; if (*size < 4) @throw [OFInvalidFormatException exception]; @@ -100,11 +100,11 @@ return field; } uint64_t -of_zip_archive_read_field64(uint8_t **data, uint16_t *size) +of_zip_archive_read_field64(const uint8_t **data, uint16_t *size) { uint64_t field = 0; if (*size < 8) @throw [OFInvalidFormatException exception]; @@ -374,11 +374,11 @@ self = [super init]; @try { uint16_t fileNameLength, extraFieldLength; of_string_encoding_t encoding; - uint8_t *ZIP64; + const uint8_t *ZIP64; uint16_t ZIP64Size; if ([stream readLittleEndianInt32] != 0x04034B50) @throw [OFInvalidFormatException exception]; @@ -396,12 +396,12 @@ ? OF_STRING_ENCODING_UTF_8 : OF_STRING_ENCODING_CODEPAGE_437); _fileName = [[stream readStringWithLength: fileNameLength encoding: encoding] copy]; - _extraField = [[stream - readDataArrayWithCount: extraFieldLength] retain]; + _extraField = + [[stream readDataWithCount: extraFieldLength] copy]; of_zip_archive_entry_extra_field_find(_extraField, OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64, &ZIP64, &ZIP64Size); if (ZIP64 != NULL) { Index: src/OFZIPArchiveEntry.h ================================================================== --- src/OFZIPArchiveEntry.h +++ src/OFZIPArchiveEntry.h @@ -75,11 +75,11 @@ enum { OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64 = 0x0001 }; @class OFString; -@class OFDataArray; +@class OFData; @class OFFile; @class OFDate; /*! * @class OFZIPArchiveEntry OFZIPArchiveEntry.h ObjFW/OFZIPArchiveEntry.h @@ -93,11 +93,11 @@ uint16_t _compressionMethod; uint16_t _lastModifiedFileTime, _lastModifiedFileDate; uint32_t _CRC32; uint64_t _compressedSize, _uncompressedSize; OFString *_fileName; - OFDataArray *_extraField; + OFData *_extraField; OFString *_fileComment; uint32_t _startDiskNumber; uint16_t _internalAttributes; uint32_t _versionSpecificAttributes; int64_t _localFileHeaderOffset; @@ -187,11 +187,11 @@ /*! * @brief Returns the extra field of the entry. * * @return The extra field of the entry */ -- (OFDataArray *)extraField; +- (OFData *)extraField; @end #ifdef __cplusplus extern "C" { #endif @@ -212,12 +212,12 @@ * @param tag The tag to look for * @param data A pointer to a pointer that should be set to the start of the * extra field with the specified tag * @param size A pointer to an uint16_t that should be set to the size */ -extern void of_zip_archive_entry_extra_field_find(OFDataArray *extraField, - uint16_t tag, uint8_t *_Nonnull *_Nonnull data, uint16_t *size); +extern void of_zip_archive_entry_extra_field_find(OFData *extraField, + uint16_t tag, const uint8_t *_Nonnull *_Nonnull data, uint16_t *size); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/OFZIPArchiveEntry.m ================================================================== --- src/OFZIPArchiveEntry.m +++ src/OFZIPArchiveEntry.m @@ -19,19 +19,19 @@ #include #import "OFZIPArchiveEntry.h" #import "OFZIPArchiveEntry+Private.h" #import "OFString.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFDate.h" #import "OFStream.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" -extern uint32_t of_zip_archive_read_field32(uint8_t **, uint16_t *); -extern uint64_t of_zip_archive_read_field64(uint8_t **, uint16_t *); +extern uint32_t of_zip_archive_read_field32(const uint8_t **, uint16_t *); +extern uint64_t of_zip_archive_read_field64(const uint8_t **, uint16_t *); OFString * of_zip_archive_entry_version_to_string(uint16_t version) { const char *attrCompat = NULL; @@ -108,14 +108,14 @@ @"%u.%u, unknown %02X", (version % 0xFF) / 10, (version & 0xFF) % 10, version >> 8]; } void -of_zip_archive_entry_extra_field_find(OFDataArray *extraField, uint16_t tag, - uint8_t **data, uint16_t *size) +of_zip_archive_entry_extra_field_find(OFData *extraField, uint16_t tag, + const uint8_t **data, uint16_t *size) { - uint8_t *bytes = [extraField items]; + const uint8_t *bytes = [extraField items]; size_t count = [extraField count]; for (size_t i = 0; i < count;) { uint16_t currentTag, currentSize; @@ -166,11 +166,11 @@ @try { void *pool = objc_autoreleasePoolPush(); uint16_t fileNameLength, extraFieldLength, fileCommentLength; of_string_encoding_t encoding; - uint8_t *ZIP64 = NULL; + const uint8_t *ZIP64 = NULL; uint16_t ZIP64Size; if ([stream readLittleEndianInt32] != 0x02014B50) @throw [OFInvalidFormatException exception]; @@ -195,12 +195,12 @@ ? OF_STRING_ENCODING_UTF_8 : OF_STRING_ENCODING_CODEPAGE_437); _fileName = [[stream readStringWithLength: fileNameLength encoding: encoding] copy]; - _extraField = [[stream - readDataArrayWithCount: extraFieldLength] retain]; + _extraField = + [[stream readDataWithCount: extraFieldLength] copy]; _fileComment = [[stream readStringWithLength: fileCommentLength encoding: encoding] copy]; of_zip_archive_entry_extra_field_find(_extraField, OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64, &ZIP64, &ZIP64Size); @@ -264,11 +264,11 @@ objc_autoreleasePoolPop(pool); return [date autorelease]; } -- (OFDataArray *)extraField +- (OFData *)extraField { return [[_extraField copy] autorelease]; } - (OFString *)description Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -18,12 +18,11 @@ #import "OFBlock.h" #import "OFAutoreleasePool.h" #import "OFString.h" -#import "OFDataArray.h" -#import "OFBigDataArray.h" +#import "OFData.h" #import "OFArray.h" #import "OFList.h" #import "OFSortedList.h" Index: src/base64.h ================================================================== --- src/base64.h +++ src/base64.h @@ -24,17 +24,17 @@ #import "macros.h" OF_ASSUME_NONNULL_BEGIN @class OFString; -@class OFDataArray; +@class OFMutableData; #ifdef __cplusplus extern "C" { #endif extern OFString *of_base64_encode(const void *, size_t); -extern bool of_base64_decode(OFDataArray *, const char *, size_t); +extern bool of_base64_decode(OFMutableData *, const char *, size_t); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/base64.m ================================================================== --- src/base64.m +++ src/base64.m @@ -15,11 +15,11 @@ */ #include "config.h" #import "OFString.h" -#import "OFDataArray.h" +#import "OFData.h" #import "base64.h" const uint8_t of_base64_encode_table[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', @@ -94,11 +94,11 @@ return ret; } bool -of_base64_decode(OFDataArray *data, const char *string, size_t length) +of_base64_decode(OFMutableData *data, const char *string, size_t length) { const uint8_t *buffer = (const uint8_t *)string; size_t i; if ((length & 3) != 0) Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -9,11 +9,11 @@ PROG_NOINST = tests${PROG_SUFFIX} SRCS = ForwardingTests.m \ OFArrayTests.m \ ${OFBLOCKTESTS_M} \ - OFDataArrayTests.m \ + OFDataTests.m \ OFDateTests.m \ OFDictionaryTests.m \ OFHTTPCookieTests.m \ OFHTTPCookieManagerTests.m \ OFJSONTests.m \ DELETED tests/OFDataArrayTests.m Index: tests/OFDataArrayTests.m ================================================================== --- tests/OFDataArrayTests.m +++ tests/OFDataArrayTests.m @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * 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 "OFDataArray.h" -#import "OFBigDataArray.h" -#import "OFString.h" -#import "OFAutoreleasePool.h" - -#import "OFOutOfRangeException.h" - -#import "TestsAppDelegate.h" - -static OFString *module; -const char *str = "Hello!"; - -@implementation TestsAppDelegate (OFDataArrayTests) -- (void)dataArrayTestsWithClass: (Class)class -{ - OFDataArray *array[4]; - void *data[2]; - Class other; - - TEST(@"+[dataArrayWithItemSize:]", - (array[0] = [class dataArrayWithItemSize: 4096])) - - data[0] = [array[0] allocMemoryWithSize: 4096]; - data[1] = [array[0] allocMemoryWithSize: 4096]; - memset(data[0], 0xFF, 4096); - memset(data[1], 0x42, 4096); - - TEST(@"-[addItem:]", R([array[0] addItem: data[0]]) && - R([array[0] addItem: data[1]])) - - TEST(@"-[itemAtIndex:]", - !memcmp([array[0] itemAtIndex: 0], data[0], 4096) && - !memcmp([array[0] itemAtIndex: 1], data[1], 4096)) - - TEST(@"-[lastItem]", !memcmp([array[0] lastItem], data[1], 4096)) - - TEST(@"-[count]", [array[0] count] == 2) - - other = (class == [OFDataArray class] - ? [OFBigDataArray class] - : [OFDataArray class]); - TEST(@"-[isEqual:]", (array[1] = [other dataArrayWithItemSize: 4096]) && - R([array[1] addItems: [array[0] items] - count: [array[0] count]]) && - [array[1] isEqual: array[0]] && - R([array[1] removeLastItem]) && ![array[0] isEqual: array[1]]) - - TEST(@"-[copy]", (array[1] = [[array[0] copy] autorelease]) && - [array[0] isEqual: array[1]]) - - array[2] = [OFDataArray dataArray]; - array[3] = [OFDataArray dataArray]; - [array[2] addItem: "a"]; - [array[2] addItem: "a"]; - [array[3] addItem: "z"]; - TEST(@"-[compare]", [array[0] compare: array[1]] == 0 && - R([array[1] removeLastItem]) && - [array[0] compare: array[1]] == OF_ORDERED_DESCENDING && - [array[1] compare: array[0]] == OF_ORDERED_ASCENDING && - [array[2] compare: array[3]] == OF_ORDERED_ASCENDING) - - TEST(@"-[hash]", [array[0] hash] == 0x634A529F) - - array[0] = [class dataArray]; - [array[0] addItems: "abcdef" - count: 6]; - - TEST(@"-[removeLastItem]", R([array[0] removeLastItem]) && - [array[0] count] == 5 && - !memcmp([array[0] items], "abcde", 5)) - - TEST(@"-[removeItemsInRange:]", - R([array[0] removeItemsInRange: of_range(1, 2)]) && - [array[0] count] == 3 && !memcmp([array[0] items], "ade", 3)) - - TEST(@"-[insertItems:atIndex:count:]", - R([array[0] insertItems: "bc" - atIndex: 1 - count: 2]) && [array[0] count] == 5 && - !memcmp([array[0] items], "abcde", 5)) - - TEST(@"-[MD5Hash]", [[array[0] MD5Hash] isEqual: [@"abcde" MD5Hash]]) - - TEST(@"-[RIPEMD160Hash]", [[array[0] RIPEMD160Hash] - isEqual: [@"abcde" RIPEMD160Hash]]) - - TEST(@"-[SHA1Hash]", [[array[0] SHA1Hash] isEqual: [@"abcde" SHA1Hash]]) - - TEST(@"-[SHA224Hash]", [[array[0] SHA224Hash] - isEqual: [@"abcde" SHA224Hash]]) - - TEST(@"-[SHA256Hash]", [[array[0] SHA256Hash] - isEqual: [@"abcde" SHA256Hash]]) - - TEST(@"-[SHA384Hash]", [[array[0] SHA384Hash] - isEqual: [@"abcde" SHA384Hash]]) - - TEST(@"-[SHA512Hash]", [[array[0] SHA512Hash] - isEqual: [@"abcde" SHA512Hash]]) - - TEST(@"-[stringByBase64Encoding]", - [[array[0] stringByBase64Encoding] isEqual: @"YWJjZGU="]) - - TEST(@"+[dataArrayWithBase64EncodedString:]", - !memcmp([[class dataArrayWithBase64EncodedString: @"YWJjZGU="] - items], "abcde", 5)) - - TEST(@"Building strings", - (array[0] = [class dataArray]) && - R([array[0] addItems: (void *)str - count: 6]) && R([array[0] addItem: ""]) && - !strcmp([array[0] items], str)) - - EXPECT_EXCEPTION(@"Detect out of range in -[itemAtIndex:]", - OFOutOfRangeException, [array[0] itemAtIndex: [array[0] count]]) - - EXPECT_EXCEPTION(@"Detect out of range in -[addItems:count:]", - OFOutOfRangeException, [array[0] addItems: data[0] - count: SIZE_MAX]) - - EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]", - OFOutOfRangeException, - [array[0] removeItemsInRange: of_range([array[0] count], 1)]) -} - -- (void)dataArrayTests -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - - module = @"OFDataArray"; - [self dataArrayTestsWithClass: [OFDataArray class]]; - - module = @"OFBigDataArray"; - [self dataArrayTestsWithClass: [OFBigDataArray class]]; - - [pool drain]; -} -@end ADDED tests/OFDataTests.m Index: tests/OFDataTests.m ================================================================== --- tests/OFDataTests.m +++ tests/OFDataTests.m @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFData.h" +#import "OFString.h" +#import "OFAutoreleasePool.h" + +#import "OFOutOfRangeException.h" + +#import "TestsAppDelegate.h" + +static OFString *module = @"OFData"; +const char *str = "Hello!"; + +@implementation TestsAppDelegate (OFDataTests) +- (void)dataTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFMutableData *mutable; + OFData *immutable; + void *raw[2]; + + TEST(@"+[dataWithItemSize:]", + (mutable = [OFMutableData dataWithItemSize: 4096])) + + OFObject *tmp = [[[OFObject alloc] init] autorelease]; + raw[0] = [tmp allocMemoryWithSize: 4096]; + raw[1] = [tmp allocMemoryWithSize: 4096]; + memset(raw[0], 0xFF, 4096); + memset(raw[1], 0x42, 4096); + + TEST(@"-[addItem:]", R([mutable addItem: raw[0]]) && + R([mutable addItem: raw[1]])) + + TEST(@"-[itemAtIndex:]", + memcmp([mutable itemAtIndex: 0], raw[0], 4096) == 0 && + memcmp([mutable itemAtIndex: 1], raw[1], 4096) == 0) + + TEST(@"-[lastItem]", memcmp([mutable lastItem], raw[1], 4096) == 0) + + TEST(@"-[count]", [mutable count] == 2) + + TEST(@"-[isEqual:]", + (immutable = [OFData dataWithItems: [mutable items] + itemSize: [mutable itemSize] + count: [mutable count]]) && + [immutable isEqual: mutable] && + R([mutable removeLastItem]) && ![mutable isEqual: immutable]) + + TEST(@"-[mutableCopy]", + (mutable = [[immutable mutableCopy] autorelease]) && + [mutable isEqual: immutable]) + + TEST(@"-[compare]", [mutable compare: immutable] == 0 && + R([mutable removeLastItem]) && + [immutable compare: mutable] == OF_ORDERED_DESCENDING && + [mutable compare: immutable] == OF_ORDERED_ASCENDING && + [[OFData dataWithItems: "aa" + count: 2] compare: + [OFData dataWithItems: "z" + count: 1]] == OF_ORDERED_ASCENDING) + + TEST(@"-[hash]", [immutable hash] == 0x634A529F) + + mutable = [OFMutableData dataWithItems: "abcdef" + count: 6]; + + TEST(@"-[removeLastItem]", R([mutable removeLastItem]) && + [mutable count] == 5 && + memcmp([mutable items], "abcde", 5) == 0) + + TEST(@"-[removeItemsInRange:]", + R([mutable removeItemsInRange: of_range(1, 2)]) && + [mutable count] == 3 && memcmp([mutable items], "ade", 3) == 0) + + TEST(@"-[insertItems:atIndex:count:]", + R([mutable insertItems: "bc" + atIndex: 1 + count: 2]) && [mutable count] == 5 && + memcmp([mutable items], "abcde", 5) == 0) + + TEST(@"-[MD5Hash]", [[mutable MD5Hash] isEqual: [@"abcde" MD5Hash]]) + + TEST(@"-[RIPEMD160Hash]", [[mutable RIPEMD160Hash] + isEqual: [@"abcde" RIPEMD160Hash]]) + + TEST(@"-[SHA1Hash]", [[mutable SHA1Hash] isEqual: [@"abcde" SHA1Hash]]) + + TEST(@"-[SHA224Hash]", [[mutable SHA224Hash] + isEqual: [@"abcde" SHA224Hash]]) + + TEST(@"-[SHA256Hash]", [[mutable SHA256Hash] + isEqual: [@"abcde" SHA256Hash]]) + + TEST(@"-[SHA384Hash]", [[mutable SHA384Hash] + isEqual: [@"abcde" SHA384Hash]]) + + TEST(@"-[SHA512Hash]", [[mutable SHA512Hash] + isEqual: [@"abcde" SHA512Hash]]) + + TEST(@"-[stringByBase64Encoding]", + [[mutable stringByBase64Encoding] isEqual: @"YWJjZGU="]) + + TEST(@"+[dataWithBase64EncodedString:]", + memcmp([[OFData dataWithBase64EncodedString: @"YWJjZGU="] + items], "abcde", 5) == 0) + + TEST(@"Building strings", + (mutable = [OFMutableData dataWithItems: str + count: 6]) && + R([mutable addItem: ""]) && + strcmp([mutable items], str) == 0) + + EXPECT_EXCEPTION(@"Detect out of range in -[itemAtIndex:]", + OFOutOfRangeException, [mutable itemAtIndex: [mutable count]]) + + EXPECT_EXCEPTION(@"Detect out of range in -[addItems:count:]", + OFOutOfRangeException, [mutable addItems: raw[0] + count: SIZE_MAX]) + + EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]", + OFOutOfRangeException, + [mutable removeItemsInRange: of_range([mutable count], 1)]) + + [pool drain]; +} +@end Index: tests/OFHTTPClientTests.m ================================================================== --- tests/OFHTTPClientTests.m +++ tests/OFHTTPClientTests.m @@ -26,11 +26,11 @@ #import "OFTCPSocket.h" #import "OFThread.h" #import "OFCondition.h" #import "OFURL.h" #import "OFDictionary.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFAutoreleasePool.h" #import "TestsAppDelegate.h" static OFString *module = @"OFHTTPClient"; @@ -91,11 +91,11 @@ HTTPClientTestsServer *server; OFURL *URL; OFHTTPClient *client; OFHTTPRequest *request; OFHTTPResponse *response = nil; - OFDataArray *data; + OFData *data; cond = [OFCondition condition]; [cond lock]; server = [[[HTTPClientTestsServer alloc] init] autorelease]; @@ -115,13 +115,13 @@ TEST(@"Normalization of server header keys", [[response headers] objectForKey: @"Content-Length"] != nil) TEST(@"Correct parsing of data", - (data = [response readDataArrayTillEndOfStream]) && - [data count] == 7 && !memcmp([data items], "foo\nbar", 7)) + (data = [response readDataUntilEndOfStream]) && + [data count] == 7 && memcmp([data items], "foo\nbar", 7) == 0) [server join]; [pool drain]; } @end Index: tests/OFSerializationTests.m ================================================================== --- tests/OFSerializationTests.m +++ tests/OFSerializationTests.m @@ -24,11 +24,11 @@ #import "OFCountedSet.h" #import "OFList.h" #import "OFNumber.h" #import "OFDate.h" #import "OFURL.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFAutoreleasePool.h" #import "OFXMLElement.h" #import "TestsAppDelegate.h" @@ -39,11 +39,11 @@ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFMutableDictionary *d = [OFMutableDictionary dictionary]; OFMutableArray *a = [OFMutableArray array]; OFList *l = [OFList list]; - OFDataArray *da = [OFDataArray dataArray]; + OFData *data; OFString *s; [a addObject: @"Qu\"xbar\ntest"]; [a addObject: [OFNumber numberWithInt: 1234]]; [a addObject: [OFNumber numberWithDouble: 1234.5678]]; @@ -65,14 +65,14 @@ [OFCountedSet setWithObjects: @"foo", @"foo", @"bar", nil]]; [d setObject: @"list" forKey: l]; - [da addItems: "0123456789:; list - MDEyMzQ1Njc4OTo7PEFCQ0RFRkdISklLTE1OT1BRUlNUVVZXWFla + MDEyMzQ1Njc4OTo7PEFCQ0RFRkdISklLTE1OT1BRUlNUVVZXWFla data Index: utils/ofhttp/OFHTTP.m ================================================================== --- utils/ofhttp/OFHTTP.m +++ utils/ofhttp/OFHTTP.m @@ -16,11 +16,11 @@ #include "config.h" #import "OFApplication.h" #import "OFArray.h" -#import "OFDataArray.h" +#import "OFData.h" #import "OFDictionary.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFHTTPClient.h" #import "OFHTTPRequest.h" @@ -57,11 +57,11 @@ OFArray OF_GENERIC(OFString *) *_URLs; size_t _URLIndex; int _errorCode; OFString *_outputPath; bool _continue, _force, _detectFileName, _quiet, _verbose, _insecure; - OFDataArray *_body; + OFData *_body; of_http_request_method_t _method; OFMutableDictionary *_clientHeaders; OFHTTPClient *_HTTPClient; char *_buffer; OFStream *_output; @@ -165,15 +165,15 @@ [_body release]; if ([file isEqual: @"-"]) { void *pool = objc_autoreleasePoolPush(); - _body = [[of_stdin readDataArrayTillEndOfStream] retain]; + _body = [[of_stdin readDataUntilEndOfStream] copy]; objc_autoreleasePoolPop(pool); } else - _body = [[OFDataArray alloc] initWithContentsOfFile: file]; + _body = [[OFData alloc] initWithContentsOfFile: file]; } - (void)setMethod: (OFString *)method { void *pool = objc_autoreleasePoolPush();