Index: .travis.yml ================================================================== --- .travis.yml +++ .travis.yml @@ -242,185 +242,9 @@ - config=wii services: docker before_install: - - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then - case "$TRAVIS_CPU_ARCH" in - amd64 | s390x) - pkgs="gobjc-multilib"; - ;; - *) - pkgs="gobjc"; - ;; - esac; - - pkgs="$pkgs libsctp-dev"; - - if grep precise /etc/lsb-release >/dev/null; then - pkgs="$pkgs ipx"; - fi; - - if ! sudo apt-get -qq install -y $pkgs >/tmp/apt_log 2>&1; then - cat /tmp/apt_log; - exit 1; - fi; - - if grep precise /etc/lsb-release >/dev/null; then - sudo ipx_internal_net add 1234 123456; - fi; - fi - - - if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" ]; then - docker pull devkitpro/devkitarm; - fi - - - if [ "$config" = "wii" ]; then - docker pull devkitpro/devkitppc; - fi - - - if [ "$config" = "amigaos" ]; then - wget -q https://franke.ms/download/amiga-gcc.tgz; - tar -C / -xzf amiga-gcc.tgz; - fi + - .travis/before_install.sh script: - - build() { - if ! git clean -fxd >/tmp/clean_log 2>&1; then - cat /tmp/clean_log; - exit 1; - fi; - ./autogen.sh || exit 1; - .travis/build.sh "$@" || exit 1; - } - - - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then - build_32_64() { - build OBJC="$CC" $@; - - case "$TRAVIS_CPU_ARCH" in - amd64) - build OBJC="$CC -m32" - --host=i686-pc-linux-gnu $@; - ;; - s390x) - build OBJC="$CC -m31" - --host=s390-pc-linux-gnu $@; - ;; - esac - }; - - build_32_64; - build_32_64 --enable-seluid24; - build_32_64 --disable-compiler-tls; - - true The following are not CPU-dependent, so only run them on amd64; - if [ "$TRAVIS_CPU_ARCH" = "amd64" ]; then - build_32_64 --disable-threads; - build_32_64 --disable-threads --disable-sockets; - build_32_64 --disable-threads --disable-files; - build_32_64 --disable-threads --disable-sockets - --disable-files; - build_32_64 --disable-sockets; - build_32_64 --disable-sockets --disable-files; - build_32_64 --disable-files; - build_32_64 --disable-shared; - build_32_64 --disable-shared --enable-seluid24; - build_32_64 --disable-compiler-tls --disable-threads; - fi; - fi - - - if [ "$TRAVIS_OS_NAME" = "osx" -a -z "$config" ]; then - build_mac_32_64() { - build $@; - if [ -z "$no32bit" ]; then - build OBJC="clang -m32" --host=i386-apple-darwin $@; - fi; - }; - - if xcodebuild -version | grep 'Xcode 6' >/dev/null; then - export CPPFLAGS="-D_Nullable=__nullable - -D_Nonnull=__nonnull - -D_Null_unspecified=__null_unspecified"; - fi; - - build_mac_32_64; - build_mac_32_64 --disable-threads; - build_mac_32_64 --disable-threads --disable-sockets; - build_mac_32_64 --disable-threads --disable-files; - build_mac_32_64 --disable-threads --disable-sockets --disable-files; - build_mac_32_64 --disable-sockets; - build_mac_32_64 --disable-sockets --disable-files; - build_mac_32_64 --disable-files; - build_mac_32_64 --disable-shared; - if [ -z "$noruntime" ]; then - build_mac_32_64 --enable-runtime; - build_mac_32_64 --enable-runtime --enable-seluid24; - build_mac_32_64 --enable-runtime --disable-threads; - build_mac_32_64 --enable-runtime --disable-threads - --disable-sockets; - build_mac_32_64 --enable-runtime --disable-threads - --disable-files; - build_mac_32_64 --enable-runtime --disable-threads - --disable-sockets --disable-files; - build_mac_32_64 --enable-runtime --disable-sockets; - build_mac_32_64 --enable-runtime --disable-sockets - --disable-files; - build_mac_32_64 --enable-runtime --disable-files; - build_mac_32_64 --enable-runtime --disable-shared; - build_mac_32_64 --enable-runtime --disable-shared - --enable-seluid24; - fi; - fi - - - if [ "$config" = "ios" ]; then - if xcodebuild -version | grep 'Xcode 6' >/dev/null; then - export CPPFLAGS="-D_Nullable=__nullable - -D_Nonnull=__nonnull - -D_Null_unspecified=__null_unspecified"; - fi; - - export IPHONEOS_DEPLOYMENT_TARGET="9.0"; - clang="clang -isysroot $(xcrun --sdk iphoneos --show-sdk-path)"; - export OBJC="$clang -arch armv7 -arch arm64"; - export OBJCPP="$clang -arch armv7 -E"; - build --host=arm-apple-darwin --enable-static; - - sysroot="$(xcrun --sdk iphonesimulator --show-sdk-path)"; - clang="clang -isysroot $sysroot"; - export OBJC="$clang -arch i386 -arch x86_64"; - export OBJCPP="$clang -arch i386 -E"; - build WRAPPER=true --host=i386-apple-darwin --enable-static; - fi - - - if [ "$config" = "amigaos" ]; then - export PATH="/opt/amiga/bin:$PATH"; - - build --host=m68k-amigaos; - build --host=m68k-amigaos --disable-amiga-lib; - build --host=m68k-amigaos --enable-static; - fi - - - if [ "$config" = "nintendo_3ds" ]; then - ./autogen.sh; - docker run -e DEVKITPRO=/opt/devkitpro - -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" - -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm - /objfw/.travis/build.sh --host=arm-none-eabi --with-3ds; - fi - - - if [ "$config" = "nintendo_ds" ]; then - ./autogen.sh; - docker run -e DEVKITPRO=/opt/devkitpro - -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" - -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm - /objfw/.travis/build.sh --host=arm-none-eabi --with-nds; - fi - - - if [ "$config" = "wii" ]; then - ./autogen.sh; - docker run -e DEVKITPRO=/opt/devkitpro - -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" - -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitppc - /objfw/.travis/build.sh ac_cv_prog_wiiload= - --host=powerpc-eabi --with-wii; - fi + - .travis/script.sh ADDED .travis/before_install.sh Index: .travis/before_install.sh ================================================================== --- .travis/before_install.sh +++ .travis/before_install.sh @@ -0,0 +1,47 @@ +#!/bin/sh +if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then + case "$TRAVIS_CPU_ARCH" in + amd64 | s390x) + pkgs="gobjc-multilib" + ;; + *) + pkgs="gobjc" + ;; + esac + + pkgs="$pkgs libsctp-dev" + + if grep precise /etc/lsb-release >/dev/null; then + pkgs="$pkgs ipx" + fi + + # We don't need any of them and they're often broken. + sudo rm -f /etc/apt/sources.list.d/* + + if ! sudo apt-get -qq update >/tmp/apt_log 2>&1; then + cat /tmp/apt_log + exit 1 + fi + + if ! sudo apt-get -qq install -y $pkgs >>/tmp/apt_log 2>&1; then + cat /tmp/apt_log + exit 1 + fi + + if grep precise /etc/lsb-release >/dev/null; then + sudo ipx_internal_net add 1234 123456 + fi +fi + +if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" ]; then + docker pull devkitpro/devkitarm +fi + +if [ "$config" = "wii" ]; then + docker pull devkitpro/devkitppc +fi + +if [ "$config" = "amigaos" ]; then + wget -q https://franke.ms/download/amiga-gcc.tgz + tar -C / -xzf amiga-gcc.tgz +fi ADDED .travis/script.sh Index: .travis/script.sh ================================================================== --- .travis/script.sh +++ .travis/script.sh @@ -0,0 +1,143 @@ +#!/bin/sh +build() { + if ! git clean -fxd >/tmp/clean_log 2>&1; then + cat /tmp/clean_log + exit 1 + fi + + ./autogen.sh || exit 1 + .travis/build.sh "$@" || exit 1 +} + +if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then + build_32_64() { + build OBJC="$CC" $@ + + case "$TRAVIS_CPU_ARCH" in + amd64) + build OBJC="$CC -m32" \ + --host=i686-pc-linux-gnu $@ + ;; + s390x) + build OBJC="$CC -m31" \ + --host=s390-pc-linux-gnu $@ + ;; + esac + } + + build_32_64 + build_32_64 --enable-seluid24 + build_32_64 --disable-compiler-tls + + # The following are not CPU-dependent, so only run them on amd64 + if [ "$TRAVIS_CPU_ARCH" = "amd64" ]; then + build_32_64 --disable-threads + build_32_64 --disable-threads --disable-sockets + build_32_64 --disable-threads --disable-files + build_32_64 --disable-threads --disable-sockets --disable-files + build_32_64 --disable-sockets + build_32_64 --disable-sockets --disable-files + build_32_64 --disable-files + build_32_64 --disable-shared + build_32_64 --disable-shared --enable-seluid24 + build_32_64 --disable-compiler-tls --disable-threads + fi +fi + +if [ "$TRAVIS_OS_NAME" = "osx" -a -z "$config" ]; then + build_mac_32_64() { + build $@ + + if [ -z "$no32bit" ]; then + build OBJC="clang -m32" --host=i386-apple-darwin $@ + fi + } + + if xcodebuild -version | grep 'Xcode 6' >/dev/null; then + export CPPFLAGS="-D_Null_unspecified=__null_unspecified" + export CPPFLAGS="$CPPFLAGS -D_Nullable=__nullable" + export CPPFLAGS="$CPPFLAGS -D_Nonnull=__nonnull" + fi + + build_mac_32_64 + build_mac_32_64 --disable-threads + build_mac_32_64 --disable-threads --disable-sockets + build_mac_32_64 --disable-threads --disable-files + build_mac_32_64 --disable-threads --disable-sockets --disable-files + build_mac_32_64 --disable-sockets + build_mac_32_64 --disable-sockets --disable-files + build_mac_32_64 --disable-files + build_mac_32_64 --disable-shared + + if [ -z "$noruntime" ]; then + build_mac_32_64 --enable-runtime + build_mac_32_64 --enable-runtime --enable-seluid24 + build_mac_32_64 --enable-runtime --disable-threads + build_mac_32_64 --enable-runtime --disable-threads \ + --disable-sockets + build_mac_32_64 --enable-runtime --disable-threads \ + --disable-files + build_mac_32_64 --enable-runtime --disable-threads \ + --disable-sockets --disable-files + build_mac_32_64 --enable-runtime --disable-sockets + build_mac_32_64 --enable-runtime --disable-sockets \ + --disable-files + build_mac_32_64 --enable-runtime --disable-files + build_mac_32_64 --enable-runtime --disable-shared + build_mac_32_64 --enable-runtime --disable-shared \ + --enable-seluid24 + fi +fi + +if [ "$config" = "ios" ]; then + if xcodebuild -version | grep 'Xcode 6' >/dev/null; then + export CPPFLAGS="-D_Null_unspecified=__null_unspecified" + export CPPFLAGS="$CPPFLAGS -D_Nullable=__nullable" + export CPPFLAGS="$CPPFLAGS -D_Nonnull=__nonnull" + fi + + export IPHONEOS_DEPLOYMENT_TARGET="9.0" + clang="clang -isysroot $(xcrun --sdk iphoneos --show-sdk-path)" + export OBJC="$clang -arch armv7 -arch arm64" + export OBJCPP="$clang -arch armv7 -E" + build --host=arm-apple-darwin --enable-static + + sysroot="$(xcrun --sdk iphonesimulator --show-sdk-path)" + clang="clang -isysroot $sysroot" + export OBJC="$clang -arch i386 -arch x86_64" + export OBJCPP="$clang -arch i386 -E" + build WRAPPER=true --host=i386-apple-darwin --enable-static +fi + +if [ "$config" = "amigaos" ]; then + export PATH="/opt/amiga/bin:$PATH" + + build --host=m68k-amigaos + build --host=m68k-amigaos --disable-amiga-lib + build --host=m68k-amigaos --enable-static +fi + +if [ "$config" = "nintendo_3ds" ]; then + ./autogen.sh + docker run -e DEVKITPRO=/opt/devkitpro \ + -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ + -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm \ + /objfw/.travis/build.sh --host=arm-none-eabi --with-3ds +fi + +if [ "$config" = "nintendo_ds" ]; then + ./autogen.sh + docker run -e DEVKITPRO=/opt/devkitpro \ + -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ + -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm \ + /objfw/.travis/build.sh --host=arm-none-eabi --with-nds +fi + +if [ "$config" = "wii" ]; then + ./autogen.sh + docker run -e DEVKITPRO=/opt/devkitpro \ + -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \ + -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitppc \ + /objfw/.travis/build.sh ac_cv_prog_wiiload= \ + --host=powerpc-eabi --with-wii +fi Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -654,16 +654,21 @@ AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-lobjc") ], [ AC_MSG_ERROR([libobjc not found!]) ]) + old_OBJCFLAGS="$OBJCFLAGS" + OBJCFLAGS="$OBJCFLAGS -lobjc" + AC_CHECK_FUNC(objc_autoreleasePoolPush, [], [ AC_SUBST(RUNTIME_AUTORELEASE_M, "runtime/autorelease.m") ]) AC_CHECK_FUNC(objc_constructInstance, [], [ AC_SUBST(RUNTIME_INSTANCE_M, "runtime/instance.m") ]) + + OBJCFLAGS="$old_OBJCFLAGS" ;; esac AC_CHECK_FUNCS(_Unwind_Backtrace) @@ -696,10 +701,45 @@ AC_SUBST(TESTS_STATIC_LIB, tests.a) TESTS_LIBS="$TESTS_LIBS -framework CoreFoundation" ]) ;; esac + +AC_MSG_CHECKING(whether Objective C compiler supports ARC) +old_OBJCFLAGS="$OBJCFLAGS" +OBJCFLAGS="$OBJCFLAGS -fobjc-arc -fobjc-arc-exceptions" +AC_TRY_COMPILE([ + #ifdef __has_attribute + # if __has_attribute(objc_root_class) + __attribute__((__objc_root_class__)) + # endif + #endif + @interface Foo + { + struct objc_class *_isa; + } + + + (id)alloc; + @end + + @implementation Foo + + (id)alloc + { + return (id)0; + } + @end +], [ + __weak id foo = [Foo alloc]; + (void)foo; +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(COMPILER_SUPPORTS_ARC, 1, [Whether the compiler supports ARC]) + AC_SUBST(RUNTIME_ARC_TESTS_M, RuntimeARCTests.m) +], [ + AC_MSG_RESULT(no) +]) +OBJCFLAGS="$old_OBJCFLAGS" AC_C_BIGENDIAN([ AC_DEFINE(OF_BIG_ENDIAN, 1, [Whether we are big endian]) ]) AS_IF([test x"$ac_cv_c_bigendian" = x"universal"], [ Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -75,10 +75,11 @@ OF_SCTP_SOCKET_M = @OF_SCTP_SOCKET_M@ OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@ REEXPORT_RUNTIME = @REEXPORT_RUNTIME@ REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@ RUNTIME = @RUNTIME@ +RUNTIME_ARC_TESTS_M = @RUNTIME_ARC_TESTS_M@ RUNTIME_AUTORELEASE_M = @RUNTIME_AUTORELEASE_M@ RUNTIME_FRAMEWORK_LIBS = @RUNTIME_FRAMEWORK_LIBS@ RUNTIME_INSTANCE_M = @RUNTIME_INSTANCE_M@ RUNTIME_LIBS = @RUNTIME_LIBS@ RUN_TESTS = @RUN_TESTS@ Index: generators/TableGenerator.m ================================================================== --- generators/TableGenerator.m +++ generators/TableGenerator.m @@ -76,11 +76,15 @@ } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response + exception: (id)exception { + if (exception != nil) + @throw exception; + [of_stdout writeLine: @" done"]; switch (_state) { case STATE_UNICODE_DATA: [self parseUnicodeData: response]; @@ -89,17 +93,10 @@ [self parseCaseFolding: response]; break; } } -- (void)client: (OFHTTPClient *)client - didFailWithException: (id)exception - request: (OFHTTPRequest *)request -{ - @throw exception; -} - - (void)parseUnicodeData: (OFHTTPResponse *)response { OFString *line; OFHTTPRequest *request; Index: src/OFASN1BitString.m ================================================================== --- src/OFASN1BitString.m +++ src/OFASN1BitString.m @@ -170,16 +170,16 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { - return _bitStringValue.hash + (uint32_t)_bitStringLength; + return _bitStringValue.hash + (unsigned long)_bitStringLength; } - (OFString *)description { return [OFString stringWithFormat: @"", _bitStringValue, _bitStringLength]; } @end Index: src/OFASN1Boolean.m ================================================================== --- src/OFASN1Boolean.m +++ src/OFASN1Boolean.m @@ -102,17 +102,17 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { - return (uint32_t)_booleanValue; + return _booleanValue; } - (OFString *)description { return (_booleanValue ? @"" : @""); } @end Index: src/OFASN1Enumerated.m ================================================================== --- src/OFASN1Enumerated.m +++ src/OFASN1Enumerated.m @@ -89,16 +89,16 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { - return (uint32_t)_longLongValue; + return (unsigned long)_longLongValue; } - (OFString *)description { return [OFString stringWithFormat: @"", _longLongValue]; } @end Index: src/OFASN1IA5String.m ================================================================== --- src/OFASN1IA5String.m +++ src/OFASN1IA5String.m @@ -110,11 +110,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { return _IA5StringValue.hash; } - (OFString *)description Index: src/OFASN1Integer.m ================================================================== --- src/OFASN1Integer.m +++ src/OFASN1Integer.m @@ -111,16 +111,16 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { - return (uint32_t)_longLongValue; + return (unsigned long)_longLongValue; } - (OFString *)description { return [OFString stringWithFormat: @"", _longLongValue]; } @end Index: src/OFASN1NumericString.m ================================================================== --- src/OFASN1NumericString.m +++ src/OFASN1NumericString.m @@ -122,11 +122,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { return _numericStringValue.hash; } - (OFString *)description Index: src/OFASN1ObjectIdentifier.m ================================================================== --- src/OFASN1ObjectIdentifier.m +++ src/OFASN1ObjectIdentifier.m @@ -167,11 +167,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { return _subidentifiers.hash; } - (OFString *)description Index: src/OFASN1OctetString.m ================================================================== --- src/OFASN1OctetString.m +++ src/OFASN1OctetString.m @@ -95,11 +95,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { return _octetStringValue.hash; } - (OFString *)description Index: src/OFASN1PrintableString.m ================================================================== --- src/OFASN1PrintableString.m +++ src/OFASN1PrintableString.m @@ -142,11 +142,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { return _printableStringValue.hash; } - (OFString *)description Index: src/OFASN1UTF8String.m ================================================================== --- src/OFASN1UTF8String.m +++ src/OFASN1UTF8String.m @@ -109,11 +109,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { return _UTF8StringValue.hash; } - (OFString *)description Index: src/OFASN1Value.m ================================================================== --- src/OFASN1Value.m +++ src/OFASN1Value.m @@ -97,11 +97,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFAdjacentArray.m ================================================================== --- src/OFAdjacentArray.m +++ src/OFAdjacentArray.m @@ -306,11 +306,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { id const *objects = _array.items; size_t count = _array.count; uint32_t hash; Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -257,14 +257,12 @@ "Warning: Invalid environment " "variable: %s\n", tmp.UTF8String); continue; } - key = [tmp substringWithRange: - of_range(0, pos)]; - value = [tmp substringWithRange: - of_range(pos + 1, tmp.length - pos - 1)]; + key = [tmp substringToIndex: pos]; + value = [tmp substringFromRange: pos + 1]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); @@ -303,14 +301,12 @@ "Warning: Invalid environment " "variable: %s\n", tmp.UTF8String); continue; } - key = [tmp substringWithRange: - of_range(0, pos)]; - value = [tmp substringWithRange: - of_range(pos + 1, tmp.length - pos - 1)]; + key = [tmp substringToIndex: pos]; + value = [tmp substringFromIndex: pos + 1]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -238,23 +238,25 @@ buffer[i] = [self objectAtIndex: range.location + i]; } - (id const *)objects { - OFObject *container; - size_t count; - id *buffer; - - container = [[[OFObject alloc] init] autorelease]; - count = self.count; - buffer = [container allocMemoryWithSize: sizeof(*buffer) - count: count]; - - [self getObjects: buffer - inRange: of_range(0, count)]; - - return buffer; + size_t count = self.count; + id *buffer = of_malloc(count, sizeof(id)); + + @try { + [self getObjects: buffer + inRange: of_range(0, count)]; + + return [[OFData dataWithItemsNoCopy: buffer + count: count + itemSize: sizeof(id) + freeWhenDone: true] items]; + } @catch (id e) { + free(buffer); + @throw e; + } } - (id)copy { return [self retain]; @@ -379,21 +381,19 @@ if (![self isKindOfClass: [OFMutableArray class]]) return [OFSubarray arrayWithArray: self range: range]; - buffer = [self allocMemoryWithSize: sizeof(*buffer) - count: range.length]; - + buffer = of_malloc(range.length, sizeof(*buffer)); @try { [self getObjects: buffer inRange: range]; ret = [OFArray arrayWithObjects: buffer count: range.length]; } @finally { - [self freeMemory: buffer]; + free(buffer); } return ret; } @@ -513,11 +513,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -856,12 +856,11 @@ #ifdef OF_HAVE_BLOCKS - (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block { OFArray *ret; size_t count = self.count; - id *tmp = [self allocMemoryWithSize: sizeof(id) - count: count]; + id *tmp = of_malloc(count, sizeof(id)); @try { [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { tmp[idx] = block(object, idx); @@ -868,22 +867,21 @@ }]; ret = [OFArray arrayWithObjects: tmp count: count]; } @finally { - [self freeMemory: tmp]; + free(tmp); } return ret; } - (OFArray *)filteredArrayUsingBlock: (of_array_filter_block_t)block { OFArray *ret; size_t count = self.count; - id *tmp = [self allocMemoryWithSize: sizeof(id) - count: count]; + id *tmp = of_malloc(count, sizeof(id)); @try { __block size_t i = 0; [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, @@ -893,11 +891,11 @@ }]; ret = [OFArray arrayWithObjects: tmp count: i]; } @finally { - [self freeMemory: tmp]; + free(tmp); } return ret; } Index: src/OFBitSetCharacterSet.m ================================================================== --- src/OFBitSetCharacterSet.m +++ src/OFBitSetCharacterSet.m @@ -47,12 +47,11 @@ @throw [OFOutOfRangeException exception]; newSize = OF_ROUND_UP_POW2(8, c + 1) / 8; - _bitset = [self resizeMemory: _bitset - size: newSize]; + _bitset = of_realloc(_bitset, newSize, 1); memset(_bitset + _size, '\0', newSize - _size); _size = newSize; } @@ -65,14 +64,21 @@ @throw e; } return self; } + +- (void)dealloc +{ + free(_bitset); + + [super dealloc]; +} - (bool)characterIsMember: (of_unichar_t)character { if (character / 8 >= _size) return false; return of_bitset_isset(_bitset, character); } @end Index: src/OFBlock.m ================================================================== --- src/OFBlock.m +++ src/OFBlock.m @@ -437,39 +437,10 @@ - (instancetype)init { OF_INVALID_INIT_METHOD } -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)ptr -{ - OF_UNRECOGNIZED_SELECTOR -} - - (instancetype)retain { if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock]) return Block_copy(self); Index: src/OFBytesValue.m ================================================================== --- src/OFBytesValue.m +++ src/OFBytesValue.m @@ -29,20 +29,27 @@ self = [super init]; @try { _size = of_sizeof_type_encoding(objCType); _objCType = objCType; - _bytes = [self allocMemoryWithSize: _size]; + _bytes = of_malloc(1, _size); memcpy(_bytes, bytes, _size); } @catch (id e) { [self release]; @throw e; } return self; } + +- (void)dealloc +{ + free(_bytes); + + [super dealloc]; +} - (void)getValue: (void *)value size: (size_t)size { if (size != _size) Index: src/OFColor.m ================================================================== --- src/OFColor.m +++ src/OFColor.m @@ -120,11 +120,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; float tmp; OF_HASH_INIT(hash); Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -52,39 +52,10 @@ + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)pointer -{ - OF_UNRECOGNIZED_SELECTOR -} - - (instancetype)retain { return self; } @@ -140,64 +111,31 @@ struct of_string_utf8_ivars *ivars; if ([self isMemberOfClass: [OFConstantUTF8String class]]) return; - if ((ivars = calloc(1, sizeof(*ivars))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: sizeof(*ivars)]; - + ivars = of_calloc(1, sizeof(*ivars)); ivars->cString = _cString; ivars->cStringLength = _cStringLength; switch (of_string_utf8_check(ivars->cString, - ivars->cStringLength, - &ivars->length)) { - case 1: - ivars->isUTF8 = true; - break; - case -1: - free(ivars); - @throw [OFInvalidEncodingException exception]; + ivars->cStringLength, &ivars->length)) { + case 1: + ivars->isUTF8 = true; + break; + case -1: + free(ivars); + @throw [OFInvalidEncodingException exception]; } _cString = (char *)ivars; object_setClass(self, [OFConstantUTF8String class]); } } + (instancetype)alloc { - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)pointer -{ OF_UNRECOGNIZED_SELECTOR } - (instancetype)retain { @@ -258,11 +196,11 @@ [self finishInitialization]; return [self isEqual: object]; } -- (uint32_t)hash +- (unsigned long)hash { [self finishInitialization]; return self.hash; } @@ -402,10 +340,24 @@ { [self finishInitialization]; return [self containsString: string]; } + +- (OFString *)substringFromIndex: (size_t)idx +{ + [self finishInitialization]; + + return [self substringFromIndex: idx]; +} + +- (OFString *)substringToIndex: (size_t)idx +{ + [self finishInitialization]; + + return [self substringToIndex: idx]; +} - (OFString *)substringWithRange: (of_range_t)range { [self finishInitialization]; Index: src/OFDNSQuery.m ================================================================== --- src/OFDNSQuery.m +++ src/OFDNSQuery.m @@ -91,11 +91,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _domainName.hash); Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -557,10 +557,11 @@ [_settings release]; [_delegate release]; [_queryData release]; [_TCPSocket release]; [_TCPQueryData release]; + free(_TCPBuffer); [_cancelTimer release]; [super dealloc]; } @end @@ -1135,12 +1136,11 @@ context->_responseLength = 0; return nil; } if (context->_TCPBuffer == nil) - context->_TCPBuffer = - [context allocMemoryWithSize: MAX_DNS_RESPONSE_LENGTH]; + context->_TCPBuffer = of_malloc(MAX_DNS_RESPONSE_LENGTH, 1); [sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: 2]; return nil; } Index: src/OFDNSResolverSettings.m ================================================================== --- src/OFDNSResolverSettings.m +++ src/OFDNSResolverSettings.m @@ -93,12 +93,11 @@ size_t pos = [domain rangeOfString: @"."].location; if (pos == OF_NOT_FOUND) return nil; - ret = [domain substringWithRange: - of_range(pos + 1, domain.length - pos - 1)]; + ret = [domain substringFromIndex: pos + 1]; } return ret; } #endif @@ -192,11 +191,11 @@ size_t pos; OFString *address; pos = [line rangeOfString: @"#"].location; if (pos != OF_NOT_FOUND) - line = [line substringWithRange: of_range(0, pos)]; + line = [line substringToIndex: pos]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OF_STRING_SKIP_EMPTY]; @@ -241,37 +240,33 @@ { @try { if ([option hasPrefix: @"ndots:"]) { unsigned long long number; - option = [option substringWithRange: - of_range(6, option.length - 6)]; + option = [option substringFromIndex: 6]; number = option.unsignedLongLongValue; if (number > UINT_MAX) @throw [OFOutOfRangeException exception]; _minNumberOfDotsInAbsoluteName = (unsigned int)number; } else if ([option hasPrefix: @"timeout:"]) { - option = [option substringWithRange: - of_range(8, option.length - 8)]; + option = [option substringFromIndex: 8]; _timeout = option.unsignedLongLongValue; } else if ([option hasPrefix: @"attempts:"]) { unsigned long long number; - option = [option substringWithRange: - of_range(9, option.length - 9)]; + option = [option substringFromIndex: 9]; number = option.unsignedLongLongValue; if (number > UINT_MAX) @throw [OFOutOfRangeException exception]; _maxAttempts = (unsigned int)number; } else if ([option hasPrefix: @"reload-period:"]) { - option = [option substringWithRange: - of_range(14, option.length - 14)]; + option = [option substringFromIndex: 14]; _configReloadInterval = option.unsignedLongLongValue; } else if ([option isEqual: @"tcp"]) _usesTCP = true; } @catch (OFInvalidFormatException *e) { @@ -306,11 +301,11 @@ OFArray *components, *arguments; OFString *option; pos = [line indexOfCharacterFromSet: commentCharacters]; if (pos != OF_NOT_FOUND) - line = [line substringWithRange: of_range(0, pos)]; + line = [line substringToIndex: pos]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OF_STRING_SKIP_EMPTY]; Index: src/OFDNSResourceRecord.m ================================================================== --- src/OFDNSResourceRecord.m +++ src/OFDNSResourceRecord.m @@ -241,11 +241,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -327,11 +327,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -423,11 +423,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -526,11 +526,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -631,11 +631,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -732,11 +732,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -830,11 +830,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -935,11 +935,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -1071,11 +1071,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -1212,11 +1212,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -1317,11 +1317,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFDNSResponse.m ================================================================== --- src/OFDNSResponse.m +++ src/OFDNSResponse.m @@ -100,11 +100,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _domainName.hash); Index: src/OFData.h ================================================================== --- src/OFData.h +++ src/OFData.h @@ -102,17 +102,17 @@ /** * @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 + * @param itemSize The item size of a single item in bytes * @return A new autoreleased OFData */ + (instancetype)dataWithItems: (const void *)items - itemSize: (size_t)itemSize - count: (size_t)count; + count: (size_t)count + itemSize: (size_t)itemSize; /** * @brief Creates a new OFData with the specified `count` items of size 1 by * taking over ownership of the specified items pointer. * @@ -129,19 +129,19 @@ /** * @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 itemSize The item size of a single item in bytes * @param freeWhenDone Whether to free the pointer when it is no longer needed * by the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone; #ifdef OF_HAVE_FILES /** * @brief Creates a new OFData with an item size of 1, containing the data of @@ -194,17 +194,17 @@ /** * @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 + * @param itemSize The item size of a single item in bytes * @return An initialized OFData */ - (instancetype)initWithItems: (const void *)items - itemSize: (size_t)itemSize - count: (size_t)count; + count: (size_t)count + itemSize: (size_t)itemSize; /** * @brief Initializes an already allocated OFData with the specified `count` * items of size 1 by taking over ownership of the specified items * pointer. @@ -223,19 +223,19 @@ * @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 itemSize The item size of a single item in bytes * @param freeWhenDone Whether to free the pointer when it is no longer needed * by the OFData * @return An initialized OFData */ - (instancetype)initWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone; #ifdef OF_HAVE_FILES /** * @brief Initializes an already allocated OFData with an item size of 1, Index: src/OFData.m ================================================================== --- src/OFData.m +++ src/OFData.m @@ -62,16 +62,16 @@ return [[[self alloc] initWithItems: items count: count] autorelease]; } + (instancetype)dataWithItems: (const void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize { return [[[self alloc] initWithItems: items - itemSize: itemSize - count: count] autorelease]; + count: count + itemSize: itemSize] autorelease]; } + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone @@ -80,17 +80,17 @@ count: count freeWhenDone: freeWhenDone] autorelease]; } + (instancetype)dataWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { return [[[self alloc] initWithItemsNoCopy: items - itemSize: itemSize count: count + itemSize: itemSize freeWhenDone: freeWhenDone] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path @@ -117,28 +117,28 @@ - (instancetype)initWithItems: (const void *)items count: (size_t)count { return [self initWithItems: items - itemSize: 1 - count: count]; + count: count + itemSize: 1]; } - (instancetype)initWithItems: (const void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize { self = [super init]; @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; - _items = [self allocMemoryWithSize: itemSize - count: count]; + _items = of_malloc(count, itemSize); + _count = count; _itemSize = itemSize; - _count = count; + _freeWhenDone = true; memcpy(_items, items, count * itemSize); } @catch (id e) { [self release]; @throw e; @@ -150,29 +150,29 @@ - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone { return [self initWithItemsNoCopy: items - itemSize: 1 count: count + itemSize: 1 freeWhenDone: freeWhenDone]; } - (instancetype)initWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { self = [super init]; @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; _items = (unsigned char *)items; - _itemSize = itemSize; _count = count; + _itemSize = itemSize; _freeWhenDone = freeWhenDone; } @catch (id e) { [self release]; @throw e; } @@ -195,14 +195,11 @@ # if ULLONG_MAX > SIZE_MAX if (size > SIZE_MAX) @throw [OFOutOfRangeException exception]; # endif - if ((buffer = malloc((size_t)size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: (size_t)size]; - + buffer = of_malloc((size_t)size, 1); file = [[OFFile alloc] initWithPath: path mode: @"r"]; @try { [file readIntoBuffer: buffer exactLength: (size_t)size]; @@ -245,27 +242,33 @@ exceptionWithURL: URL]; stream = [URLHandler openItemAtURL: URL mode: @"r"]; - _itemSize = 1; _count = 0; + _itemSize = 1; + _freeWhenDone = true; pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; - - while (!stream.atEndOfStream) { - size_t length = [stream readIntoBuffer: buffer - length: pageSize]; - - if (SIZE_MAX - _count < length) - @throw [OFOutOfRangeException exception]; - - _items = [self resizeMemory: _items - size: _count + length]; - memcpy(_items + _count, buffer, length); - _count += length; + buffer = of_malloc(1, pageSize); + + @try { + while (!stream.atEndOfStream) { + size_t length = [stream + readIntoBuffer: buffer + length: pageSize]; + + if (SIZE_MAX - _count < length) + @throw [OFOutOfRangeException + exception]; + + _items = of_realloc(_items, _count + length, 1); + memcpy(_items + _count, buffer, length); + _count += length; + } + } @finally { + free(buffer); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @@ -287,13 +290,14 @@ if (count % 2 != 0) @throw [OFInvalidFormatException exception]; count /= 2; - _items = [self allocMemoryWithSize: count]; + _items = of_malloc(count, 1); + _count = count; _itemSize = 1; - _count = count; + _freeWhenDone = true; cString = [string cStringWithEncoding: OF_STRING_ENCODING_ASCII]; for (size_t i = 0; i < count; i++) { @@ -430,12 +434,12 @@ } - (id)mutableCopy { return [[OFMutableData alloc] initWithItems: _items - itemSize: _itemSize - count: _count]; + count: _count + itemSize: _itemSize]; } - (bool)isEqual: (id)object { OFData *data; @@ -487,11 +491,11 @@ return OF_ORDERED_DESCENDING; else return OF_ORDERED_ASCENDING; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -510,12 +514,12 @@ if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; ret = [OFData dataWithItemsNoCopy: _items + (range.location * _itemSize) - itemSize: _itemSize count: range.length + itemSize: _itemSize freeWhenDone: false]; ret->_parentData = [(_parentData != nil ? _parentData : self) copy]; return ret; } Index: src/OFDate.h ================================================================== --- src/OFDate.h +++ src/OFDate.h @@ -44,86 +44,86 @@ #endif /** * @brief The microsecond of the date. */ -@property (readonly, nonatomic) uint32_t microsecond; +@property (readonly, nonatomic) unsigned long microsecond; /** * @brief The second of the date. */ -@property (readonly, nonatomic) uint8_t second; +@property (readonly, nonatomic) unsigned char second; /** * @brief The minute of the date. */ -@property (readonly, nonatomic) uint8_t minute; +@property (readonly, nonatomic) unsigned char minute; /** * @brief The minute of the date in local time. */ -@property (readonly, nonatomic) uint8_t localMinute; +@property (readonly, nonatomic) unsigned char localMinute; /** * @brief The hour of the date. */ -@property (readonly, nonatomic) uint8_t hour; +@property (readonly, nonatomic) unsigned char hour; /** * @brief The hour of the date in local time. */ -@property (readonly, nonatomic) uint8_t localHour; +@property (readonly, nonatomic) unsigned char localHour; /** * @brief The day of the month of the date. */ -@property (readonly, nonatomic) uint8_t dayOfMonth; +@property (readonly, nonatomic) unsigned char dayOfMonth; /** * @brief The day of the month of the date in local time. */ -@property (readonly, nonatomic) uint8_t localDayOfMonth; +@property (readonly, nonatomic) unsigned char localDayOfMonth; /** * @brief The month of the year of the date. */ -@property (readonly, nonatomic) uint8_t monthOfYear; +@property (readonly, nonatomic) unsigned char monthOfYear; /** * @brief The month of the year of the date in local time. */ -@property (readonly, nonatomic) uint8_t localMonthOfYear; +@property (readonly, nonatomic) unsigned char localMonthOfYear; /** * @brief The year of the date. */ -@property (readonly, nonatomic) uint16_t year; +@property (readonly, nonatomic) unsigned short year; /** * @brief The year of the date in local time. */ -@property (readonly, nonatomic) uint16_t localYear; +@property (readonly, nonatomic) unsigned short localYear; /** * @brief The day of the week of the date. */ -@property (readonly, nonatomic) uint8_t dayOfWeek; +@property (readonly, nonatomic) unsigned char dayOfWeek; /** * @brief The day of the week of the date in local time. */ -@property (readonly, nonatomic) uint8_t localDayOfWeek; +@property (readonly, nonatomic) unsigned char localDayOfWeek; /** * @brief The day of the year of the date. */ -@property (readonly, nonatomic) uint16_t dayOfYear; +@property (readonly, nonatomic) unsigned short dayOfYear; /** * @brief The day of the year of the date in local time. */ -@property (readonly, nonatomic) uint16_t localDayOfYear; +@property (readonly, nonatomic) unsigned short localDayOfYear; /** * @brief The seconds since 1970-01-01T00:00:00Z. */ @property (readonly, nonatomic) of_time_interval_t timeIntervalSince1970; Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -221,11 +221,11 @@ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, }; static double -tmAndTzToTime(struct tm *tm, int16_t *tz) +tmAndTzToTime(const struct tm *tm, short tz) { double seconds; /* Years */ seconds = (int64_t)(tm->tm_year - 70) * 31536000; @@ -249,11 +249,11 @@ /* Minutes */ seconds += tm->tm_min * 60; /* Seconds */ seconds += tm->tm_sec; /* Time zone */ - seconds += -(double)*tz * 60; + seconds += -(double)tz * 60; return seconds; } @implementation OFDateSingleton @@ -440,40 +440,40 @@ format: (OFString *)format { void *pool = objc_autoreleasePoolPush(); const char *UTF8String = string.UTF8String; struct tm tm = { .tm_isdst = -1 }; - int16_t tz = 0; + short tz = 0; if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); - return [self initWithTimeIntervalSince1970: tmAndTzToTime(&tm, &tz)]; + return [self initWithTimeIntervalSince1970: tmAndTzToTime(&tm, tz)]; } - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format { void *pool = objc_autoreleasePoolPush(); const char *UTF8String = string.UTF8String; struct tm tm = { .tm_isdst = -1 }; /* - * of_strptime() can never set this to INT16_MAX, no matter what is + * of_strptime() can never set this to SHRT_MAX, no matter what is * passed to it, so this is a safe way to figure out if the date * contains a time zone. */ - int16_t tz = INT16_MAX; + short tz = SHRT_MAX; of_time_interval_t seconds; if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; - if (tz == INT16_MAX) { + if (tz == SHRT_MAX) { #ifdef OF_WINDOWS if (func__mktime64 != NULL) { if ((seconds = func__mktime64(&tm)) == -1) @throw [OFInvalidFormatException exception]; } else { @@ -482,11 +482,11 @@ @throw [OFInvalidFormatException exception]; #ifdef OF_WINDOWS } #endif } else - seconds = tmAndTzToTime(&tm, &tz); + seconds = tmAndTzToTime(&tm, tz); objc_autoreleasePoolPop(pool); return [self initWithTimeIntervalSince1970: seconds]; } @@ -536,11 +536,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; double tmp; OF_HASH_INIT(hash); @@ -656,88 +656,88 @@ objc_autoreleasePoolPop(pool); return [ret autorelease]; } -- (uint32_t)microsecond +- (unsigned long)microsecond { of_time_interval_t timeInterval = self.timeIntervalSince1970; - return (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000); + return (unsigned long)((timeInterval - trunc(timeInterval)) * 1000000); } -- (uint8_t)second +- (unsigned char)second { GMTIME_RET(tm_sec) } -- (uint8_t)minute +- (unsigned char)minute { GMTIME_RET(tm_min) } -- (uint8_t)localMinute +- (unsigned char)localMinute { LOCALTIME_RET(tm_min) } -- (uint8_t)hour +- (unsigned char)hour { GMTIME_RET(tm_hour) } -- (uint8_t)localHour +- (unsigned char)localHour { LOCALTIME_RET(tm_hour) } -- (uint8_t)dayOfMonth +- (unsigned char)dayOfMonth { GMTIME_RET(tm_mday) } -- (uint8_t)localDayOfMonth +- (unsigned char)localDayOfMonth { LOCALTIME_RET(tm_mday) } -- (uint8_t)monthOfYear +- (unsigned char)monthOfYear { GMTIME_RET(tm_mon + 1) } -- (uint8_t)localMonthOfYear +- (unsigned char)localMonthOfYear { LOCALTIME_RET(tm_mon + 1) } -- (uint16_t)year +- (unsigned short)year { GMTIME_RET(tm_year + 1900) } -- (uint16_t)localYear +- (unsigned short)localYear { LOCALTIME_RET(tm_year + 1900) } -- (uint8_t)dayOfWeek +- (unsigned char)dayOfWeek { GMTIME_RET(tm_wday) } -- (uint8_t)localDayOfWeek +- (unsigned char)localDayOfWeek { LOCALTIME_RET(tm_wday) } -- (uint16_t)dayOfYear +- (unsigned short)dayOfYear { GMTIME_RET(tm_yday + 1) } -- (uint16_t)localDayOfYear +- (unsigned short)localDayOfYear { LOCALTIME_RET(tm_yday + 1) } - (OFString *)dateStringWithFormat: (OFConstantString *)format @@ -777,14 +777,11 @@ } # endif #endif pageSize = [OFSystemInfo pageSize]; - if ((buffer = malloc(pageSize)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: pageSize]; - + buffer = of_malloc(1, pageSize); @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; @@ -840,14 +837,11 @@ } # endif #endif pageSize = [OFSystemInfo pageSize]; - if ((buffer = malloc(pageSize)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: pageSize]; - + buffer = of_malloc(1, pageSize); @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -595,22 +595,22 @@ return new; } #endif -- (uint32_t)hash +- (unsigned long)hash { void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; id key, object; - uint32_t hash = 0; + unsigned long hash = 0; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { - hash += [key hash]; - hash += [object hash]; + hash ^= [key hash]; + hash ^= [object hash]; } objc_autoreleasePoolPop(pool); return hash; Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -241,14 +241,11 @@ @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: errno]; #else - if ((handle = malloc(sizeof(*handle))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: sizeof(*handle)]; - + handle = of_malloc(1, sizeof(*handle)); @try { if ((flags = parseMode(mode.UTF8String, &handle->append)) == -1) @throw [OFInvalidArgumentException exception]; Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -631,14 +631,11 @@ size_t pageSize = [OFSystemInfo pageSize]; OFStream *sourceStream = nil; OFStream *destinationStream = nil; char *buffer; - if ((buffer = malloc(pageSize)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: pageSize]; - + buffer = of_malloc(1, pageSize); @try { sourceStream = [[OFURLHandler handlerForURL: source] openItemAtURL: source mode: @"r"]; destinationStream = [[OFURLHandler handlerForURL: Index: src/OFHTTPClient.h ================================================================== --- src/OFHTTPClient.h +++ src/OFHTTPClient.h @@ -40,27 +40,17 @@ /** * @brief A callback which is called when an OFHTTPClient performed a request. * * @param client The OFHTTPClient which performed the request * @param request The request the OFHTTPClient performed - * @param response The response to the request performed + * @param response The response to the request performed, or nil on error + * @param exception An exception if the request failed, or nil on success */ - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request - response: (OFHTTPResponse *)response; - -/** - * @brief A callback which is called when an OFHTTPClient encountered an - * exception while performing a request. - * - * @param client The client which encountered an exception - * @param exception The exception the client encountered - * @param request The request during which the client encountered the exception - */ -- (void)client: (OFHTTPClient *)client - didFailWithException: (id)exception - request: (OFHTTPRequest *)request; + response: (nullable OFHTTPResponse *)response + exception: (nullable id)exception; @optional /** * @brief A callback which is called when an OFHTTPClient creates a socket. * @@ -99,11 +89,11 @@ * @param request The request for which the headers and status code have been * received */ - (void)client: (OFHTTPClient *)client didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers - statusCode: (int)statusCode + statusCode: (short)statusCode request: (OFHTTPRequest *)request; /** * @brief A callback which is called when an OFHTTPClient wants to follow a * redirect. @@ -128,11 +118,11 @@ * @param response The response indicating the redirect * @return A boolean whether the OFHTTPClient should follow the redirect */ - (bool)client: (OFHTTPClient *)client shouldFollowRedirect: (OFURL *)URL - statusCode: (int)statusCode + statusCode: (short)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response; @end /** Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -60,11 +60,11 @@ OFHTTPClient *_client; OFHTTPRequest *_request; unsigned int _redirects; bool _firstLine; OFString *_version; - int _status; + short _status; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_serverHeaders; } - (instancetype)initWithClient: (OFHTTPClient *)client request: (OFHTTPRequest *)request @@ -239,11 +239,11 @@ str++; } } static bool -defaultShouldFollow(of_http_request_method_t method, int statusCode) +defaultShouldFollow(of_http_request_method_t method, short statusCode) { bool follow; /* * 301, 302 and 307 should only redirect with user confirmation if the @@ -296,21 +296,23 @@ { [_client close]; _client->_inProgress = false; [_client->_delegate client: _client - didFailWithException: exception - request: _request]; + didPerformRequest: _request + response: nil + exception: exception]; } - (void)createResponseWithSocketOrThrow: (OFTCPSocket *)sock { OFURL *URL = _request.URL; OFHTTPClientResponse *response; OFString *connectionHeader; bool keepAlive; OFString *location; + id exception; response = [[[OFHTTPClientResponse alloc] initWithSocket: sock] autorelease]; response.protocolVersionString = _version; response.statusCode = _status; @@ -420,19 +422,22 @@ } _client->_inProgress = false; if (_status / 100 != 2) - @throw [OFHTTPRequestFailedException + exception = [OFHTTPRequestFailedException exceptionWithRequest: _request response: response]; + else + exception = nil; [_client->_delegate performSelector: @selector(client:didPerformRequest: - response:) + response:exception:) withObject: _client withObject: _request withObject: response + withObject: exception afterDelay: 0]; } - (void)createResponseWithSocket: (OFTCPSocket *)sock { @@ -469,11 +474,11 @@ status = [line substringWithRange: of_range(9, 3)].longLongValue; if (status < 0 || status > 599) @throw [OFInvalidServerReplyException exception]; - _status = (int)status; + _status = (short)status; return true; } - (bool)handleServerHeader: (OFString *)line @@ -508,14 +513,11 @@ lineC = line.UTF8String; if ((tmp = strchr(lineC, ':')) == NULL) @throw [OFInvalidServerReplyException exception]; - if ((keyC = malloc(tmp - lineC + 1)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: tmp - lineC + 1]; - + keyC = of_malloc(tmp - lineC + 1, 1); memcpy(keyC, lineC, tmp - lineC); keyC[tmp - lineC] = '\0'; normalizeKey(keyC); @try { @@ -998,11 +1000,11 @@ return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; - of_range_t range; + size_t pos; @try { line = [_socket tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidServerReplyException exception]; @@ -1009,22 +1011,20 @@ } if (line == nil) return 0; - range = [line rangeOfString: @";"]; - if (range.location != OF_NOT_FOUND) - line = [line substringWithRange: - of_range(0, range.location)]; + pos = [line rangeOfString: @";"].location; + if (pos != OF_NOT_FOUND) + line = [line substringToIndex: pos]; if (line.length < 1) { /* * We have read the empty string because the socket is * at end of stream. */ - if (_socket.atEndOfStream && - range.location == OF_NOT_FOUND) + if (_socket.atEndOfStream && pos == OF_NOT_FOUND) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidServerReplyException exception]; } @@ -1131,33 +1131,32 @@ } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response + exception: (id)exception { + if (exception != nil) { + /* + * Restore the delegate - we're giving up, but not reaching the + * release of the autorelease pool that contains us, so + * resetting it via -[dealloc] might be too late. + */ + _client.delegate = _delegate; + + @throw exception; + } + [[OFRunLoop currentRunLoop] stop]; [_response release]; _response = [response retain]; [_delegate client: client didPerformRequest: request - response: response]; -} - -- (void)client: (OFHTTPClient *)client - didFailWithException: (id)exception - request: (OFHTTPRequest *)request -{ - /* - * Restore the delegate - we're giving up, but not reaching the release - * of the autorelease pool that contains us, so resetting it via - * -[dealloc] might be too late. - */ - _client.delegate = _delegate; - - @throw exception; + response: response + exception: nil]; } - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)sock request: (OFHTTPRequest *)request @@ -1180,11 +1179,11 @@ request: request]; } - (void)client: (OFHTTPClient *)client didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers - statusCode: (int)statusCode + statusCode: (short)statusCode request: (OFHTTPRequest *)request { if ([_delegate respondsToSelector: @selector(client:didReceiveHeaders:statusCode:request:)]) [_delegate client: client @@ -1193,11 +1192,11 @@ request: request]; } - (bool)client: (OFHTTPClient *)client shouldFollowRedirect: (OFURL *)URL - statusCode: (int)statusCode + statusCode: (short)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { if ([_delegate respondsToSelector: @selector(client: shouldFollowRedirect:statusCode:request:response:)]) Index: src/OFHTTPCookie.m ================================================================== --- src/OFHTTPCookie.m +++ src/OFHTTPCookie.m @@ -361,11 +361,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); Index: src/OFHTTPCookieManager.m ================================================================== --- src/OFHTTPCookieManager.m +++ src/OFHTTPCookieManager.m @@ -136,12 +136,12 @@ URLHost = URL.host.lowercaseString; if ([cookieDomain hasPrefix: @"."]) { if ([URLHost hasSuffix: cookieDomain]) match = true; else { - cookieDomain = [cookieDomain substringWithRange: - of_range(1, cookieDomain.length - 1)]; + cookieDomain = + [cookieDomain substringFromIndex: 1]; match = [cookieDomain isEqual: URLHost]; } } else match = [cookieDomain isEqual: URLHost]; Index: src/OFHTTPRequest.h ================================================================== --- src/OFHTTPRequest.h +++ src/OFHTTPRequest.h @@ -57,13 +57,13 @@ * * @brief The HTTP version of the HTTP request. */ struct OF_BOXABLE of_http_request_protocol_version_t { /** The major of the HTTP version */ - uint8_t major; + unsigned char major; /** The minor of the HTTP version */ - uint8_t minor; + unsigned char minor; }; typedef struct of_http_request_protocol_version_t of_http_request_protocol_version_t; /** Index: src/OFHTTPRequest.m ================================================================== --- src/OFHTTPRequest.m +++ src/OFHTTPRequest.m @@ -183,11 +183,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -206,11 +206,11 @@ - (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion { if (protocolVersion.major != 1 || protocolVersion.minor > 1) @throw [OFUnsupportedVersionException exceptionWithVersion: - [OFString stringWithFormat: @"%u.%u", + [OFString stringWithFormat: @"%hhu.%hhu", protocolVersion.major, protocolVersion.minor]]; _protocolVersion = protocolVersion; } @@ -231,24 +231,24 @@ @throw [OFInvalidFormatException exception]; major = [components.firstObject unsignedLongLongValue]; minor = [components.lastObject unsignedLongLongValue]; - if (major > UINT8_MAX || minor > UINT8_MAX) + if (major > UCHAR_MAX || minor > UCHAR_MAX) @throw [OFOutOfRangeException exception]; - protocolVersion.major = (uint8_t)major; - protocolVersion.minor = (uint8_t)minor; + protocolVersion.major = (unsigned char)major; + protocolVersion.minor = (unsigned char)minor; self.protocolVersion = protocolVersion; objc_autoreleasePoolPop(pool); } - (OFString *)protocolVersionString { - return [OFString stringWithFormat: @"%u.%u", + return [OFString stringWithFormat: @"%hhu.%hhu", _protocolVersion.major, _protocolVersion.minor]; } - (OFString *)description Index: src/OFHTTPResponse.m ================================================================== --- src/OFHTTPResponse.m +++ src/OFHTTPResponse.m @@ -253,11 +253,11 @@ - (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion { if (protocolVersion.major != 1 || protocolVersion.minor > 1) @throw [OFUnsupportedVersionException exceptionWithVersion: - [OFString stringWithFormat: @"%u.%u", + [OFString stringWithFormat: @"%hhu.%hhu", protocolVersion.major, protocolVersion.minor]]; _protocolVersion = protocolVersion; } @@ -278,24 +278,24 @@ @throw [OFInvalidFormatException exception]; major = [components.firstObject unsignedLongLongValue]; minor = [components.lastObject unsignedLongLongValue]; - if (major > UINT8_MAX || minor > UINT8_MAX) + if (major > UCHAR_MAX || minor > UCHAR_MAX) @throw [OFOutOfRangeException exception]; - protocolVersion.major = (uint8_t)major; - protocolVersion.minor = (uint8_t)minor; + protocolVersion.major = (unsigned char)major; + protocolVersion.minor = (unsigned char)minor; self.protocolVersion = protocolVersion; objc_autoreleasePoolPop(pool); } - (OFString *)protocolVersionString { - return [OFString stringWithFormat: @"%u.%u", + return [OFString stringWithFormat: @"%hhu.%hhu", _protocolVersion.major, _protocolVersion.minor]; } - (OFString *)string @@ -348,15 +348,15 @@ stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; ret = [[OFString alloc] initWithFormat: @"<%@:\n" - @"\tStatus code = %d\n" + @"\tStatus code = %hd\n" @"\tHeaders = %@\n" @">", self.class, _statusCode, indentedHeaders]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -145,12 +145,17 @@ firstLetter = false; tmp++; } - return [OFString stringWithUTF8StringNoCopy: cString - freeWhenDone: true]; + @try { + return [OFString stringWithUTF8StringNoCopy: cString + freeWhenDone: true]; + } @catch (id e) { + free(cString); + @throw e; + } } @implementation OFHTTPServerResponse - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server @@ -182,11 +187,11 @@ void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; - [_socket writeFormat: @"HTTP/%@ %d %@\r\n", + [_socket writeFormat: @"HTTP/%@ %hd %@\r\n", self.protocolVersionString, _statusCode, of_http_status_code_to_string(_statusCode)]; headers = [[_headers mutableCopy] autorelease]; @@ -374,11 +379,11 @@ pos = [line rangeOfString: @" "].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; - method = [line substringWithRange: of_range(0, pos)]; + method = [line substringToIndex: pos]; @try { _method = of_http_request_method_from_string(method); } @catch (OFInvalidArgumentException *e) { return [self sendErrorAndClose: 405]; } @@ -450,13 +455,12 @@ pos = [line rangeOfString: @":"].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; - key = [line substringWithRange: of_range(0, pos)]; - value = [line substringWithRange: - of_range(pos + 1, line.length - pos - 1)]; + key = [line substringToIndex: pos]; + value = [line substringFromIndex: pos + 1]; key = normalizedKey(key.stringByDeletingTrailingWhitespaces); value = value.stringByDeletingLeadingWhitespaces; old = [_headers objectForKey: key]; @@ -471,18 +475,15 @@ rangeOfString: @":" options: OF_STRING_SEARCH_BACKWARDS].location; if (pos != OF_NOT_FOUND) { [_host release]; - _host = [[value substringWithRange: - of_range(0, pos)] retain]; + _host = [[value substringToIndex: pos] retain]; @try { - of_range_t range = - of_range(pos + 1, value.length - pos - 1); unsigned long long portTmp = - [value substringWithRange: range] + [value substringFromIndex: pos + 1] .unsignedLongLongValue; if (portTmp < 1 || portTmp > UINT16_MAX) return [self sendErrorAndClose: 400]; @@ -503,11 +504,11 @@ - (bool)sendErrorAndClose: (short)statusCode { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; - [_socket writeFormat: @"HTTP/1.1 %d %@\r\n" + [_socket writeFormat: @"HTTP/1.1 %hd %@\r\n" @"Date: %@\r\n" @"Server: %@\r\n" @"\r\n", statusCode, of_http_status_code_to_string(statusCode), @@ -546,13 +547,12 @@ URL.port = [OFNumber numberWithUnsignedShort: _port]; if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) { OFString *path, *query; - path = [_path substringWithRange: of_range(0, pos)]; - query = [_path substringWithRange: - of_range(pos + 1, _path.length - pos - 1)]; + path = [_path substringToIndex: pos]; + query = [_path substringFromIndex: pos + 1]; URL.URLEncodedPath = path; URL.URLEncodedQuery = query; } else URL.URLEncodedPath = _path; @@ -696,11 +696,11 @@ return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; - of_range_t range; + size_t pos; unsigned long long toRead; @try { line = [_socket tryReadLine]; } @catch (OFInvalidEncodingException *e) { @@ -708,22 +708,20 @@ } if (line == nil) return 0; - range = [line rangeOfString: @";"]; - if (range.location != OF_NOT_FOUND) - line = [line substringWithRange: - of_range(0, range.location)]; + pos = [line rangeOfString: @";"].location; + if (pos != OF_NOT_FOUND) + line = [line substringToIndex: pos]; if (line.length < 1) { /* * We have read the empty string because the socket is * at end of stream. */ - if (_socket.atEndOfStream && - range.location == OF_NOT_FOUND) + if (_socket.atEndOfStream && pos == OF_NOT_FOUND) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidFormatException exception]; } Index: src/OFHostAddressResolver.m ================================================================== --- src/OFHostAddressResolver.m +++ src/OFHostAddressResolver.m @@ -277,12 +277,12 @@ id exception = nil; if (_addressFamily == address.family || _addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY) addresses = [OFData dataWithItems: &address - itemSize: sizeof(address) - count: 1]; + count: 1 + itemSize: sizeof(address)]; else exception = [OFInvalidArgumentException exception]; callDelegateInMode(_runLoopMode, _delegate, _resolver, _host, addresses, exception); Index: src/OFINICategory.m ================================================================== --- src/OFINICategory.m +++ src/OFINICategory.m @@ -159,19 +159,14 @@ size_t pos; if ((pos = [line rangeOfString: @"="].location) == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; - key = [line substringWithRange: of_range(0, pos)]; - value = [line substringWithRange: - of_range(pos + 1, line.length - pos - 1)]; - - key = key.stringByDeletingEnclosingWhitespaces; - value = value.stringByDeletingEnclosingWhitespaces; - - key = unescapeString(key); - value = unescapeString(value); + key = unescapeString([line substringToIndex: pos] + .stringByDeletingEnclosingWhitespaces); + value = unescapeString([line substringFromIndex: pos + 1] + .stringByDeletingEnclosingWhitespaces); pair->_key = [key copy]; pair->_value = [value copy]; [_lines addObject: pair]; Index: src/OFINIFileSettings.m ================================================================== --- src/OFINIFileSettings.m +++ src/OFINIFileSettings.m @@ -65,13 +65,12 @@ *category = @""; *key = path; return; } - *category = [path substringWithRange: of_range(0, pos)]; - *key = [path substringWithRange: - of_range(pos + 1, path.length - pos - 1)]; + *category = [path substringToIndex: pos]; + *key = [path substringFromIndex: pos + 1]; } - (void)setString: (OFString *)string forPath: (OFString *)path { Index: src/OFIPSocketAsyncConnector.m ================================================================== --- src/OFIPSocketAsyncConnector.m +++ src/OFIPSocketAsyncConnector.m @@ -244,12 +244,12 @@ of_socket_address_t address = of_socket_address_parse_ip(_host, _port); _socketAddresses = [[OFData alloc] initWithItems: &address - itemSize: sizeof(address) - count: 1]; + count: 1 + itemSize: sizeof(address)]; [self tryNextAddressWithRunLoopMode: runLoopMode]; return; } @catch (OFInvalidFormatException *e) { } Index: src/OFInflateStream.m ================================================================== --- src/OFInflateStream.m +++ src/OFInflateStream.m @@ -194,12 +194,11 @@ #ifdef OF_INFLATE64_STREAM_M _slidingWindowMask = 0xFFFF; #else _slidingWindowMask = 0x7FFF; #endif - _slidingWindow = [self allocZeroedMemoryWithSize: - _slidingWindowMask + 1]; + _slidingWindow = of_calloc(_slidingWindowMask + 1, 1); } @catch (id e) { [self release]; @throw e; } @@ -209,14 +208,19 @@ - (void)dealloc { if (_stream != nil) [self close]; - if (_state == HUFFMAN_TREE) + free(_slidingWindow); + + if (_state == HUFFMAN_TREE) { + free(_context.huffmanTree.lengths); + if (_context.huffmanTree.codeLenTree != NULL) of_huffman_tree_release( _context.huffmanTree.codeLenTree); + } if (_state == HUFFMAN_TREE || _state == HUFFMAN_BLOCK) { if (_context.huffman.litLenTree != fixedLitLenTree) of_huffman_tree_release(_context.huffman.litLenTree); if (_context.huffman.distTree != fixedDistTree) @@ -374,12 +378,11 @@ CTX.codeLenCodesCount = bits; } if OF_LIKELY (CTX.lengths == NULL) - CTX.lengths = [self - allocZeroedMemoryWithSize: 19]; + CTX.lengths = of_calloc(19, 1); for (uint16_t i = CTX.receivedCount; i < CTX.codeLenCodesCount + 4; i++) { if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) { CTX.receivedCount = i; @@ -391,19 +394,19 @@ CTX.codeLenTree = of_huffman_tree_construct( CTX.lengths, 19); CTX.treeIter = CTX.codeLenTree; - [self freeMemory: CTX.lengths]; + free(CTX.lengths); CTX.lengths = NULL; CTX.receivedCount = 0; CTX.value = 0xFF; } if OF_LIKELY (CTX.lengths == NULL) - CTX.lengths = [self allocMemoryWithSize: - CTX.litLenCodesCount + CTX.distCodesCount + 258]; + CTX.lengths = of_malloc( + CTX.litLenCodesCount + CTX.distCodesCount + 258, 1); for (uint16_t i = CTX.receivedCount; i < CTX.litLenCodesCount + CTX.distCodesCount + 258;) { uint8_t j, count; @@ -482,11 +485,11 @@ CTX.litLenCodesCount + 257); CTX.distTree = of_huffman_tree_construct( CTX.lengths + CTX.litLenCodesCount + 257, CTX.distCodesCount + 1); - [self freeMemory: CTX.lengths]; + free(CTX.lengths); /* * litLenTree and distTree are at the same location in * _context.huffman and _context.huffmanTree, thus no need to * set them. Index: src/OFKernelEventObserver.m ================================================================== --- src/OFKernelEventObserver.m +++ src/OFKernelEventObserver.m @@ -212,14 +212,15 @@ [_writeObjects removeObjectIdenticalTo: object]; } - (bool)of_processReadBuffers { + void *pool = objc_autoreleasePoolPush(); bool foundInReadBuffer = false; - for (id object in _readObjects) { - void *pool = objc_autoreleasePoolPush(); + for (id object in [[_readObjects copy] autorelease]) { + void *pool2 = objc_autoreleasePoolPush(); if ([object isKindOfClass: [OFStream class]] && [object hasDataInReadBuffer] && ![(OFStream *)object of_isWaitingForDelimiter]) { if ([_delegate respondsToSelector: @@ -227,12 +228,14 @@ [_delegate objectIsReadyForReading: object]; foundInReadBuffer = true; } - objc_autoreleasePoolPop(pool); + objc_autoreleasePoolPop(pool2); } + + objc_autoreleasePoolPop(pool); /* * As long as we have data in the read buffer for any stream, we don't * want to block. */ Index: src/OFLHADecompressingStream.m ================================================================== --- src/OFLHADecompressingStream.m +++ src/OFLHADecompressingStream.m @@ -108,12 +108,11 @@ _distanceBits = distanceBits; _dictionaryBits = dictionaryBits; _slidingWindowMask = (1u << dictionaryBits) - 1; - _slidingWindow = [self allocMemoryWithSize: - _slidingWindowMask + 1]; + _slidingWindow = of_malloc(_slidingWindowMask + 1, 1); memset(_slidingWindow, ' ', _slidingWindowMask + 1); } @catch (id e) { [self release]; @throw e; } @@ -123,17 +122,21 @@ - (void)dealloc { if (_stream != nil) [self close]; + + free(_slidingWindow); if (_codeLenTree != NULL) of_huffman_tree_release(_codeLenTree); if (_litLenTree != NULL) of_huffman_tree_release(_litLenTree); if (_distTree != NULL) of_huffman_tree_release(_distTree); + + free(_codesLengths); [super dealloc]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ @@ -172,11 +175,11 @@ goto start; } _codesCount = bits; _codesReceived = 0; - _codesLengths = [self allocZeroedMemoryWithSize: bits]; + _codesLengths = of_calloc(bits, 1); _skip = true; _state = STATE_CODE_LEN_TREE; goto start; case STATE_CODE_LEN_TREE: @@ -223,11 +226,12 @@ _codesReceived++; } _codeLenTree = of_huffman_tree_construct(_codesLengths, _codesCount); - [self freeMemory: _codesLengths]; + free(_codesLengths); + _codesLengths = NULL; _state = STATE_LITLEN_CODES_COUNT; goto start; case STATE_CODE_LEN_TREE_SINGLE: if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) @@ -252,11 +256,11 @@ goto start; } _codesCount = bits; _codesReceived = 0; - _codesLengths = [self allocZeroedMemoryWithSize: bits]; + _codesLengths = of_calloc(bits, 1); _skip = false; _treeIter = _codeLenTree; _state = STATE_LITLEN_TREE; goto start; @@ -312,11 +316,12 @@ _codesLengths[_codesReceived++] = value - 2; } _litLenTree = of_huffman_tree_construct(_codesLengths, _codesCount); - [self freeMemory: _codesLengths]; + free(_codesLengths); + _codesLengths = NULL; of_huffman_tree_release(_codeLenTree); _codeLenTree = NULL; _state = STATE_DIST_CODES_COUNT; @@ -341,11 +346,11 @@ goto start; } _codesCount = bits; _codesReceived = 0; - _codesLengths = [self allocZeroedMemoryWithSize: bits]; + _codesLengths = of_calloc(bits, 1); _treeIter = _codeLenTree; _state = STATE_DIST_TREE; goto start; case STATE_DIST_TREE: @@ -376,11 +381,12 @@ _codesReceived++; } _distTree = of_huffman_tree_construct(_codesLengths, _codesCount); - [self freeMemory: _codesLengths]; + free(_codesLengths); + _codesLengths = NULL; _treeIter = _litLenTree; _state = STATE_BLOCK_LITLEN; goto start; case STATE_DIST_TREE_SINGLE: Index: src/OFList.m ================================================================== --- src/OFList.m +++ src/OFList.m @@ -79,22 +79,27 @@ return self; } - (void)dealloc { + of_list_object_t *next; + for (of_list_object_t *iter = _firstListObject; - iter != NULL; iter = iter->next) + iter != NULL; iter = next) { [iter->object release]; + next = iter->next; + free(iter); + } [super dealloc]; } - (of_list_object_t *)appendObject: (id)object { of_list_object_t *listObject; - listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)]; + listObject = of_malloc(1, sizeof(of_list_object_t)); listObject->object = [object retain]; listObject->next = NULL; listObject->previous = _lastListObject; if (_lastListObject != NULL) @@ -113,11 +118,11 @@ - (of_list_object_t *)prependObject: (id)object { of_list_object_t *listObject; - listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)]; + listObject = of_malloc(1, sizeof(of_list_object_t)); listObject->object = [object retain]; listObject->next = _firstListObject; listObject->previous = NULL; if (_firstListObject != NULL) @@ -136,11 +141,11 @@ - (of_list_object_t *)insertObject: (id)object beforeListObject: (of_list_object_t *)listObject { of_list_object_t *newListObject; - newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)]; + newListObject = of_malloc(1, sizeof(of_list_object_t)); newListObject->object = [object retain]; newListObject->next = listObject; newListObject->previous = listObject->previous; if (listObject->previous != NULL) @@ -160,11 +165,11 @@ - (of_list_object_t *)insertObject: (id)object afterListObject: (of_list_object_t *)listObject { of_list_object_t *newListObject; - newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)]; + newListObject = of_malloc(1, sizeof(of_list_object_t)); newListObject->object = [object retain]; newListObject->next = listObject->next; newListObject->previous = listObject; if (listObject->next != NULL) @@ -195,12 +200,11 @@ _count--; _mutations++; [listObject->object release]; - - [self freeMemory: listObject]; + free(listObject); } - (id)firstObject { return (_firstListObject != NULL ? _firstListObject->object : nil); @@ -270,19 +274,19 @@ return false; } - (void)removeAllObjects { - of_list_object_t *iter, *next; + of_list_object_t *next; _mutations++; - for (iter = _firstListObject; iter != NULL; iter = next) { - next = iter->next; - + for (of_list_object_t *iter = _firstListObject; + iter != NULL; iter = next) { [iter->object release]; - [self freeMemory: iter]; + next = iter->next; + free(iter); } _firstListObject = _lastListObject = NULL; } @@ -295,12 +299,11 @@ previous = NULL; @try { for (of_list_object_t *iter = _firstListObject; iter != NULL; iter = iter->next) { - listObject = [copy allocMemoryWithSize: - sizeof(of_list_object_t)]; + listObject = of_malloc(1, sizeof(of_list_object_t)); listObject->object = [iter->object retain]; listObject->next = NULL; listObject->previous = previous; if (copy->_firstListObject == NULL) @@ -320,11 +323,11 @@ copy->_lastListObject = listObject; return copy; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFMapTable.h ================================================================== --- src/OFMapTable.h +++ src/OFMapTable.h @@ -31,11 +31,11 @@ /** The function to retain keys / objects */ void *_Nullable (*_Nullable retain)(void *_Nullable object); /** The function to release keys / objects */ void (*_Nullable release)(void *_Nullable object); /** The function to hash keys */ - uint32_t (*_Nullable hash)(void *_Nullable object); + unsigned long (*_Nullable hash)(void *_Nullable object); /** The function to compare keys / objects */ bool (*_Nullable equal)(void *_Nullable object1, void *_Nullable object2); }; typedef struct of_map_table_functions_t of_map_table_functions_t; @@ -74,12 +74,12 @@ OF_SUBCLASSING_RESTRICTED @interface OFMapTable: OFObject { of_map_table_functions_t _keyFunctions, _objectFunctions; struct of_map_table_bucket *_Nonnull *_Nullable _buckets; - uint32_t _count, _capacity; - uint8_t _rotate; + unsigned long _count, _capacity; + unsigned char _rotate; unsigned long _mutations; } /** * @brief The key functions used by the map table. @@ -240,14 +240,12 @@ */ @interface OFMapTableEnumerator: OFObject { OFMapTable *_mapTable; struct of_map_table_bucket *_Nonnull *_Nullable _buckets; - uint32_t _capacity; - unsigned long _mutations; - unsigned long *_Nullable _mutationsPtr; - uint32_t _position; + unsigned long _capacity, _mutations, *_Nullable _mutationsPtr; + unsigned long _position; } - (instancetype)init OF_UNAVAILABLE; /** Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -32,11 +32,11 @@ #define MIN_CAPACITY 16 struct of_map_table_bucket { void *key, *object; - uint32_t hash; + unsigned long hash; }; static struct of_map_table_bucket deleted = { 0 }; static void * defaultRetain(void *object) @@ -47,14 +47,14 @@ static void defaultRelease(void *object) { } -static uint32_t +static unsigned long defaultHash(void *object) { - return (uint32_t)(uintptr_t)object; + return (unsigned long)(uintptr_t)object; } static bool defaultEqual(void *object1, void *object2) { @@ -63,18 +63,18 @@ OF_DIRECT_MEMBERS @interface OFMapTable () - (void)of_setObject: (void *)object forKey: (void *)key - hash: (uint32_t)hash; + hash: (unsigned long)hash; @end OF_DIRECT_MEMBERS @interface OFMapTableEnumerator () - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable buckets: (struct of_map_table_bucket **)buckets - capacity: (uint32_t)capacity + capacity: (unsigned long)capacity mutationsPointer: (unsigned long *)mutationsPtr OF_METHOD_FAMILY(init); @end @interface OFMapTableKeyEnumerator: OFMapTableEnumerator @@ -143,30 +143,29 @@ SET_DEFAULT(_objectFunctions.hash, defaultHash); SET_DEFAULT(_objectFunctions.equal, defaultEqual); #undef SET_DEFAULT - if (capacity > UINT32_MAX / sizeof(*_buckets) || - capacity > UINT32_MAX / 8) + if (capacity > ULONG_MAX / sizeof(*_buckets) || + capacity > ULONG_MAX / 8) @throw [OFOutOfRangeException exception]; for (_capacity = 1; _capacity < capacity;) { - if (_capacity > UINT32_MAX / 2) + if (_capacity > ULONG_MAX / 2) @throw [OFOutOfRangeException exception]; _capacity *= 2; } if (capacity * 8 / _capacity >= 6) - if (_capacity <= UINT32_MAX / 2) + if (_capacity <= ULONG_MAX / 2) _capacity *= 2; if (_capacity < MIN_CAPACITY) _capacity = MIN_CAPACITY; - _buckets = [self allocZeroedMemoryWithSize: sizeof(*_buckets) - count: _capacity]; + _buckets = of_calloc(_capacity, sizeof(*_buckets)); if (of_hash_seed != 0) _rotate = of_random16() & 31; } @catch (id e) { [self release]; @@ -176,16 +175,20 @@ return self; } - (void)dealloc { - for (uint32_t i = 0; i < _capacity; i++) { + for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); + + free(_buckets[i]); } } + + free(_buckets); [super dealloc]; } - (bool)isEqual: (id)object @@ -203,11 +206,11 @@ if (mapTable->_count != _count || mapTable->_keyFunctions.equal != _keyFunctions.equal || mapTable->_objectFunctions.equal != _objectFunctions.equal) return false; - for (uint32_t i = 0; i < _capacity; i++) { + for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { void *objectIter = [mapTable objectForKey: _buckets[i]->key]; if (!_objectFunctions.equal(objectIter, @@ -217,18 +220,18 @@ } return true; } -- (uint32_t)hash +- (unsigned long)hash { - uint32_t hash = 0; + unsigned long hash = 0; - for (uint32_t i = 0; i < _capacity; i++) { + for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { - hash += OF_ROR(_buckets[i]->hash, _rotate); - hash += _objectFunctions.hash(_buckets[i]->object); + hash ^= OF_ROR(_buckets[i]->hash, _rotate); + hash ^= _objectFunctions.hash(_buckets[i]->object); } } return hash; } @@ -239,11 +242,11 @@ initWithKeyFunctions: _keyFunctions objectFunctions: _objectFunctions capacity: _capacity]; @try { - for (uint32_t i = 0; i < _capacity; i++) + for (unsigned long i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deleted) [copy of_setObject: _buckets[i]->object forKey: _buckets[i]->key hash: OF_ROR(_buckets[i]->hash, _rotate)]; @@ -260,11 +263,11 @@ return _count; } - (void *)objectForKey: (void *)key { - uint32_t i, hash, last; + unsigned long i, hash, last; if (key == NULL) @throw [OFInvalidArgumentException exception]; hash = OF_ROL(_keyFunctions.hash(key), _rotate); @@ -293,22 +296,22 @@ } return NULL; } -- (void)of_resizeForCount: (uint32_t)count OF_DIRECT +- (void)of_resizeForCount: (unsigned long)count OF_DIRECT { - uint32_t fullness, capacity; + unsigned long fullness, capacity; struct of_map_table_bucket **buckets; - if (count > UINT32_MAX / sizeof(*_buckets) || count > UINT32_MAX / 8) + if (count > ULONG_MAX / sizeof(*_buckets) || count > ULONG_MAX / 8) @throw [OFOutOfRangeException exception]; fullness = count * 8 / _capacity; if (fullness >= 6) { - if (_capacity > UINT32_MAX / 2) + if (_capacity > ULONG_MAX / 2) return; capacity = _capacity * 2; } else if (fullness <= 1) capacity = _capacity / 2; @@ -320,16 +323,15 @@ * below the minimum capacity. */ if ((capacity < _capacity && count > _count) || capacity < MIN_CAPACITY) return; - buckets = [self allocZeroedMemoryWithSize: sizeof(*buckets) - count: capacity]; + buckets = of_calloc(capacity, sizeof(*buckets)); - for (uint32_t i = 0; i < _capacity; i++) { + for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { - uint32_t j, last; + unsigned long j, last; last = capacity; for (j = _buckets[i]->hash & (capacity - 1); j < last && buckets[j] != NULL; j++); @@ -347,20 +349,20 @@ buckets[j] = _buckets[i]; } } - [self freeMemory: _buckets]; + free(_buckets); _buckets = buckets; _capacity = capacity; } - (void)of_setObject: (void *)object forKey: (void *)key - hash: (uint32_t)hash + hash: (unsigned long)hash { - uint32_t i, last; + unsigned long i, last; void *old; if (key == NULL || object == NULL) @throw [OFInvalidArgumentException exception]; @@ -410,24 +412,24 @@ } if (i >= last) @throw [OFOutOfRangeException exception]; - bucket = [self allocMemoryWithSize: sizeof(*bucket)]; + bucket = of_malloc(1, sizeof(*bucket)); @try { bucket->key = _keyFunctions.retain(key); } @catch (id e) { - [self freeMemory: bucket]; + free(bucket); @throw e; } @try { bucket->object = _objectFunctions.retain(object); } @catch (id e) { _keyFunctions.release(bucket->key); - [self freeMemory: bucket]; + free(bucket); @throw e; } bucket->hash = hash; @@ -450,11 +452,11 @@ hash: _keyFunctions.hash(key)]; } - (void)removeObjectForKey: (void *)key { - uint32_t i, hash, last; + unsigned long i, hash, last; if (key == NULL) @throw [OFInvalidArgumentException exception]; hash = OF_ROL(_keyFunctions.hash(key), _rotate); @@ -468,11 +470,11 @@ _mutations++; _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); - [self freeMemory: _buckets[i]]; + free(_buckets[i]); _buckets[i] = &deleted; _count--; [self of_resizeForCount: _count]; @@ -492,11 +494,11 @@ if (_keyFunctions.equal(_buckets[i]->key, key)) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); - [self freeMemory: _buckets[i]]; + free(_buckets[i]); _buckets[i] = &deleted; _count--; _mutations++; [self of_resizeForCount: _count]; @@ -506,30 +508,28 @@ } } - (void)removeAllObjects { - for (uint32_t i = 0; i < _capacity; i++) { + for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL) { if (_buckets[i] == &deleted) { _buckets[i] = NULL; continue; } _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); - [self freeMemory: _buckets[i]]; + free(_buckets[i]); _buckets[i] = NULL; } } _count = 0; _capacity = MIN_CAPACITY; - _buckets = [self resizeMemory: _buckets - size: sizeof(*_buckets) - count: _capacity]; + _buckets = of_realloc(_buckets, _capacity, sizeof(*_buckets)); /* * Get a new random value for _rotate, so that it is not less secure * than creating a new hash map. */ @@ -540,11 +540,11 @@ - (bool)containsObject: (void *)object { if (object == NULL || _count == 0) return false; - for (uint32_t i = 0; i < _capacity; i++) + for (unsigned long i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deleted) if (_objectFunctions.equal(_buckets[i]->object, object)) return true; return false; @@ -553,11 +553,11 @@ - (bool)containsObjectIdenticalTo: (void *)object { if (object == NULL || _count == 0) return false; - for (uint32_t i = 0; i < _capacity; i++) + for (unsigned long i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deleted) if (_buckets[i]->object == object) return true; return false; @@ -583,11 +583,11 @@ - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state objects: (id *)objects count: (int)count { - uint32_t j = (uint32_t)state->state; + unsigned long j = state->state; int i; for (i = 0; i < count; i++) { for (; j < _capacity && (_buckets[j] == NULL || _buckets[j] == &deleted); j++); @@ -656,11 +656,11 @@ OF_INVALID_INIT_METHOD } - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable buckets: (struct of_map_table_bucket **)buckets - capacity: (uint32_t)capacity + capacity: (unsigned long)capacity mutationsPointer: (unsigned long *)mutationsPtr { self = [super init]; _mapTable = [mapTable retain]; Index: src/OFMapTableDictionary.m ================================================================== --- src/OFMapTableDictionary.m +++ src/OFMapTableDictionary.m @@ -47,11 +47,11 @@ release(void *object) { [(id)object release]; } -static uint32_t +static unsigned long hash(void *object) { return [(id)object hash]; } @@ -342,12 +342,11 @@ OFArray *ret; id *keys; size_t count; count = _mapTable.count; - keys = [self allocMemoryWithSize: sizeof(*keys) - count: count]; + keys = of_malloc(count, sizeof(*keys)); @try { void *pool = objc_autoreleasePoolPush(); OFMapTableEnumerator *enumerator; void **keyPtr; @@ -364,11 +363,11 @@ objc_autoreleasePoolPop(pool); ret = [OFArray arrayWithObjects: keys count: count]; } @finally { - [self freeMemory: keys]; + free(keys); } return ret; } @@ -377,12 +376,11 @@ OFArray *ret; id *objects; size_t count; count = _mapTable.count; - objects = [self allocMemoryWithSize: sizeof(*objects) - count: count]; + objects = of_malloc(count, sizeof(*objects)); @try { void *pool = objc_autoreleasePoolPush(); OFMapTableEnumerator *enumerator; void **objectPtr; @@ -399,11 +397,11 @@ objc_autoreleasePoolPop(pool); ret = [OFArray arrayWithObjects: objects count: count]; } @finally { - [self freeMemory: objects]; + free(objects); } return ret; } @@ -444,10 +442,10 @@ exceptionWithObject: self]; } } #endif -- (uint32_t)hash +- (unsigned long)hash { return _mapTable.hash; } @end Index: src/OFMapTableSet.m ================================================================== --- src/OFMapTableSet.m +++ src/OFMapTableSet.m @@ -39,11 +39,11 @@ release(void *object) { [(id)object release]; } -static uint32_t +static unsigned long hash(void *object) { return [(id)object hash]; } Index: src/OFMessagePackExtension.m ================================================================== --- src/OFMessagePackExtension.m +++ src/OFMessagePackExtension.m @@ -175,11 +175,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFMethodSignature.m ================================================================== --- src/OFMethodSignature.m +++ src/OFMethodSignature.m @@ -595,11 +595,11 @@ length = strlen(types); if (length == 0) @throw [OFInvalidFormatException exception]; - _types = [self allocMemoryWithSize: length + 1]; + _types = of_malloc(length + 1, 1); memcpy(_types, types, length); _typesPointers = [[OFMutableData alloc] initWithItemSize: sizeof(char *)]; _offsets = [[OFMutableData alloc] @@ -669,10 +669,11 @@ return self; } - (void)dealloc { + free(_types); [_typesPointers release]; [_offsets release]; [super dealloc]; } Index: src/OFMutableAdjacentArray.m ================================================================== --- src/OFMutableAdjacentArray.m +++ src/OFMutableAdjacentArray.m @@ -241,22 +241,21 @@ if (range.length > SIZE_MAX - range.location || range.location >= count || range.length > count - range.location) @throw [OFOutOfRangeException exception]; - copy = [self allocMemoryWithSize: sizeof(*copy) - count: range.length]; + copy = of_malloc(range.length, sizeof(*copy)); memcpy(copy, objects + range.location, range.length * sizeof(id)); @try { [_array removeItemsInRange: range]; _mutations++; for (size_t i = 0; i < range.length; i++) [copy[i] release]; } @finally { - [self freeMemory: copy]; + free(copy); } } - (void)removeLastObject { Index: src/OFMutableData.m ================================================================== --- src/OFMutableData.m +++ src/OFMutableData.m @@ -54,10 +54,11 @@ - (instancetype)init { self = [super init]; _itemSize = 1; + _freeWhenDone = true; return self; } - (instancetype)initWithItemSize: (size_t)itemSize @@ -67,10 +68,11 @@ @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; _itemSize = itemSize; + _freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } @@ -90,44 +92,43 @@ @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; - _items = [self allocMemoryWithSize: itemSize - count: capacity]; - + _items = of_malloc(capacity, itemSize); _itemSize = itemSize; _capacity = capacity; + _freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithItems: (const void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize { self = [super initWithItems: items - itemSize: itemSize - count: count]; + count: count + itemSize: itemSize]; _capacity = _count; return self; } - (instancetype)initWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { self = [self initWithItems: items - itemSize: itemSize - count: count]; + count: count + itemSize: itemSize]; if (freeWhenDone) free(items); return self; @@ -176,23 +177,21 @@ if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; return [OFData dataWithItems: _items + (range.location * _itemSize) - itemSize: _itemSize - count: range.length]; + count: range.length + itemSize: _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]; + _items = of_realloc(_items, _count + 1, _itemSize); _capacity = _count + 1; } memcpy(_items + _count * _itemSize, item, _itemSize); @@ -212,13 +211,11 @@ { if (count > SIZE_MAX - _count) @throw [OFOutOfRangeException exception]; if (_count + count > _capacity) { - _items = [self resizeMemory: _items - size: _itemSize - count: _count + count]; + _items = of_realloc(_items, _count + count, _itemSize); _capacity = _count + count; } memcpy(_items + _count * _itemSize, items, count * _itemSize); _count += count; @@ -230,13 +227,11 @@ { if (count > SIZE_MAX - _count || idx > _count) @throw [OFOutOfRangeException exception]; if (_count + count > _capacity) { - _items = [self resizeMemory: _items - size: _itemSize - count: _count + count]; + _items = of_realloc(_items, _count + count, _itemSize); _capacity = _count + count; } memmove(_items + (idx + count) * _itemSize, _items + idx * _itemSize, (_count - idx) * _itemSize); @@ -249,13 +244,11 @@ { if (count > SIZE_MAX - _count) @throw [OFOutOfRangeException exception]; if (_count + count > _capacity) { - _items = [self resizeMemory: _items - size: _itemSize - count: _count + count]; + _items = of_realloc(_items, _count + count, _itemSize); _capacity = _count + count; } memset(_items + _count * _itemSize, '\0', count * _itemSize); _count += count; @@ -276,13 +269,11 @@ _items + (range.location + range.length) * _itemSize, (_count - range.location - range.length) * _itemSize); _count -= range.length; @try { - _items = [self resizeMemory: _items - size: _itemSize - count: _count]; + _items = of_realloc(_items, _count, _itemSize); _capacity = _count; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -292,35 +283,41 @@ if (_count == 0) return; _count--; @try { - _items = [self resizeMemory: _items - size: _itemSize - count: _count]; + _items = of_realloc(_items, _count, _itemSize); _capacity = _count; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only made it smaller */ } } - (void)removeAllItems { - [self freeMemory: _items]; - + free(_items); _items = NULL; _count = 0; _capacity = 0; } - (id)copy { return [[OFData alloc] initWithItems: _items - itemSize: _itemSize - count: _count]; + count: _count + itemSize: _itemSize]; } - (void)makeImmutable { + if (_capacity != _count) { + @try { + _items = of_realloc(_items, _count, _itemSize); + _capacity = _count; + } @catch (OFOutOfMemoryException *e) { + /* We don't care, as we only made it smaller */ + } + } + object_setClass(self, [OFData class]); } @end Index: src/OFMutableSet.m ================================================================== --- src/OFMutableSet.m +++ src/OFMutableSet.m @@ -170,13 +170,11 @@ { void *pool = objc_autoreleasePoolPush(); size_t count = self.count; id *cArray; - cArray = [self allocMemoryWithSize: sizeof(id) - count: count]; - + cArray = of_malloc(count, sizeof(id)); @try { size_t i; i = 0; for (id object in self) { @@ -186,11 +184,11 @@ for (i = 0; i < count; i++) if (![set containsObject: cArray[i]]) [self removeObject: cArray[i]]; } @finally { - [self freeMemory: cArray]; + free(cArray); } objc_autoreleasePoolPop(pool); } Index: src/OFMutableUTF8String.m ================================================================== --- src/OFMutableUTF8String.m +++ src/OFMutableUTF8String.m @@ -43,31 +43,27 @@ } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { - @try { - self = [self initWithUTF8String: UTF8String]; - } @finally { - if (freeWhenDone) - free(UTF8String); - } + self = [self initWithUTF8String: UTF8String]; + + if (freeWhenDone) + free(UTF8String); return self; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { - @try { - self = [self initWithUTF8String: UTF8String - length: UTF8StringLength]; - } @finally { - if (freeWhenDone) - free(UTF8String); - } + self = [self initWithUTF8String: UTF8String + length: UTF8StringLength]; + + if (freeWhenDone) + free(UTF8String); return self; } - (void)of_convertWithWordStartTable: (const of_unichar_t *const[])startTable @@ -103,12 +99,11 @@ return; } unicodeLen = self.length; - unicodeString = [self allocMemoryWithSize: sizeof(of_unichar_t) - count: unicodeLen]; + unicodeString = of_malloc(unicodeLen, sizeof(of_unichar_t)); i = j = 0; newCStringLength = 0; while (i < _s->cStringLength) { @@ -127,11 +122,11 @@ cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { - [self freeMemory: unicodeString]; + free(unicodeString); @throw [OFInvalidEncodingException exception]; } isStart = of_ascii_isspace(c); @@ -150,21 +145,21 @@ else if (c < 0x10000) newCStringLength += 3; else if (c < 0x110000) newCStringLength += 4; else { - [self freeMemory: unicodeString]; + free(unicodeString); @throw [OFInvalidEncodingException exception]; } i += cLen; } @try { - newCString = [self allocMemoryWithSize: newCStringLength + 1]; + newCString = of_malloc(newCStringLength + 1, 1); } @catch (id e) { - [self freeMemory: unicodeString]; + free(unicodeString); @throw e; } j = 0; @@ -171,22 +166,22 @@ for (i = 0; i < unicodeLen; i++) { size_t d; if ((d = of_string_utf8_encode(unicodeString[i], newCString + j)) == 0) { - [self freeMemory: unicodeString]; - [self freeMemory: newCString]; + free(unicodeString); + free(newCString); @throw [OFInvalidEncodingException exception]; } j += d; } assert(j == newCStringLength); newCString[j] = 0; - [self freeMemory: unicodeString]; + free(unicodeString); - [self freeMemory: _s->cString]; + free(_s->cString); _s->hashed = false; _s->cString = newCString; _s->cStringLength = newCStringLength; /* @@ -227,13 +222,12 @@ _s->hashed = false; if (lenNew == (size_t)lenOld) memcpy(_s->cString + idx, buffer, lenNew); else if (lenNew > (size_t)lenOld) { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength - - lenOld + lenNew + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength - lenOld + lenNew + 1, 1); memmove(_s->cString + idx + lenNew, _s->cString + idx + lenOld, _s->cStringLength - idx - lenOld); memcpy(_s->cString + idx, buffer, lenNew); @@ -254,13 +248,12 @@ if (character >= 0x80) _s->isUTF8 = true; @try { - _s->cString = [self - resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } } @@ -283,13 +276,12 @@ case -1: @throw [OFInvalidEncodingException exception]; } _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + - UTF8StringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength + 1); _s->cStringLength += UTF8StringLength; _s->length += length; @@ -313,13 +305,12 @@ case -1: @throw [OFInvalidEncodingException exception]; } _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + - UTF8StringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += length; @@ -361,13 +352,12 @@ @throw [OFInvalidArgumentException exception]; UTF8StringLength = string.UTF8StringLength; _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + - UTF8StringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, string.UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += string.length; @@ -383,13 +373,12 @@ } - (void)appendCharacters: (const of_unichar_t *)characters length: (size_t)length { - char *tmp; + char *tmp = of_malloc((length * 4) + 1, 1); - tmp = [self allocMemoryWithSize: (length * 4) + 1]; @try { size_t j = 0; bool isUTF8 = false; for (size_t i = 0; i < length; i++) { @@ -406,21 +395,21 @@ } tmp[j] = '\0'; _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + j + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + j + 1, 1); memcpy(_s->cString + _s->cStringLength, tmp, j + 1); _s->cStringLength += j; _s->length += length; if (isUTF8) _s->isUTF8 = true; } @finally { - [self freeMemory: tmp]; + free(tmp); } } - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments @@ -535,12 +524,11 @@ idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength); newCStringLength = _s->cStringLength + string.UTF8StringLength; _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: newCStringLength + 1]; + _s->cString = of_realloc(_s->cString, newCStringLength + 1, 1); memmove(_s->cString + idx + string.UTF8StringLength, _s->cString + idx, _s->cStringLength - idx); memcpy(_s->cString + idx, string.UTF8String, string.UTF8StringLength); @@ -578,12 +566,11 @@ _s->length -= range.length; _s->cStringLength -= end - start; _s->cString[_s->cStringLength] = 0; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -620,12 +607,11 @@ * We must not resize the string if the new string is smaller, because * then we can't memmove() the rest of the string forward as the rest is * lost due to the resize! */ if (newCStringLength > _s->cStringLength) - _s->cString = [self resizeMemory: _s->cString - size: newCStringLength + 1]; + _s->cString = of_realloc(_s->cString, newCStringLength + 1, 1); memmove(_s->cString + start + replacement.UTF8StringLength, _s->cString + end, _s->cStringLength - end); memcpy(_s->cString + start, replacement.UTF8String, replacement.UTF8StringLength); @@ -634,12 +620,11 @@ /* * If the new string is smaller, we can safely resize it now as we're * done with memmove(). */ if (newCStringLength < _s->cStringLength) - _s->cString = [self resizeMemory: _s->cString - size: newCStringLength + 1]; + _s->cString = of_realloc(_s->cString, newCStringLength + 1, 1); _s->cStringLength = newCStringLength; _s->length = newLength; if ([replacement isKindOfClass: [OFUTF8String class]] || @@ -688,16 +673,15 @@ for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(_s->cString + i, searchString, searchLength) != 0) continue; @try { - newCString = [self resizeMemory: newCString - size: newCStringLength + - i - last + - replacementLength + 1]; + newCString = of_realloc(newCString, + newCStringLength + i - last + replacementLength + 1, + 1); } @catch (id e) { - [self freeMemory: newCString]; + free(newCString); @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, i - last); memcpy(newCString + newCStringLength + i - last, @@ -709,23 +693,22 @@ i += searchLength - 1; last = i + 1; } @try { - newCString = [self resizeMemory: newCString - size: newCStringLength + - _s->cStringLength - last + 1]; + newCString = of_realloc(newCString, + newCStringLength + _s->cStringLength - last + 1, 1); } @catch (id e) { - [self freeMemory: newCString]; + free(newCString); @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, _s->cStringLength - last); newCStringLength += _s->cStringLength - last; newCString[newCStringLength] = 0; - [self freeMemory: _s->cString]; + free(_s->cString); _s->hashed = false; _s->cString = newCString; _s->cStringLength = newCStringLength; _s->length = newLength; @@ -751,12 +734,11 @@ memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -778,12 +760,11 @@ _s->cStringLength -= d; _s->length -= d; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -815,12 +796,11 @@ memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } Index: src/OFNumber.m ================================================================== --- src/OFNumber.m +++ src/OFNumber.m @@ -985,11 +985,11 @@ return OF_ORDERED_SAME; } } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFObject+KeyValueCoding.m ================================================================== --- src/OFObject+KeyValueCoding.m +++ src/OFObject+KeyValueCoding.m @@ -48,14 +48,11 @@ if ((keyLength = key.UTF8StringLength) < 1) { objc_autoreleasePoolPop(pool); return [self valueForUndefinedKey: key]; } - if ((name = malloc(keyLength + 3)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: keyLength + 3]; - + name = of_malloc(keyLength + 3, 1); @try { memcpy(name, "is", 2); memcpy(name + 2, key.UTF8String, keyLength); name[keyLength + 2] = '\0'; @@ -163,14 +160,11 @@ [self setValue: value forUndefinedKey: key]; return; } - if ((name = malloc(keyLength + 5)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: keyLength + 5]; - + name = of_malloc(keyLength + 5, 1); @try { memcpy(name, "set", 3); memcpy(name + 3, key.UTF8String, keyLength); memcpy(name + keyLength + 3, ":", 2); Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -320,11 +320,11 @@ * to behave in a way compatible to your reimplementation of this * method! * * @return A 32 bit hash for the object */ -- (uint32_t)hash; +- (unsigned long)hash; /** * @brief Returns the retain count. * * @return The retain count @@ -543,11 +543,11 @@ @property (readonly, nonatomic) Class class; # else @property (readonly, nonatomic, getter=class) Class class_; #endif @property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass; -@property (readonly, nonatomic) uint32_t hash; +@property (readonly, nonatomic) unsigned long hash; @property (readonly, nonatomic) unsigned int retainCount; @property (readonly, nonatomic) bool isProxy; @property (readonly, nonatomic) bool allowsWeakReference; /** @@ -804,101 +804,10 @@ * returned * @return The method signature for the specified selector */ - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector; -/** - * @brief Allocates memory and stores it in the object's memory pool. - * - * It will be free'd automatically when the object is deallocated. - * - * @param size The size of the memory to allocate - * @return A pointer to the allocated memory. May return NULL if the specified - * size is 0. - */ -- (nullable void *)allocMemoryWithSize: (size_t)size OF_WARN_UNUSED_RESULT; - -/** - * @brief Allocates memory for the specified number of items and stores it in - * the object's memory pool. - * - * It will be free'd automatically when the object is deallocated. - * - * @param size The size of each item to allocate - * @param count The number of items to allocate - * @return A pointer to the allocated memory. May return NULL if the specified - * size or count is 0. - */ -- (nullable void *)allocMemoryWithSize: (size_t)size - count: (size_t)count OF_WARN_UNUSED_RESULT; - -/** - * @brief Allocates memory, initializes it with zeros and stores it in the - * object's memory pool. - * - * It will be free'd automatically when the object is deallocated. - * - * @param size The size of the memory to allocate - * @return A pointer to the allocated memory. May return NULL if the specified - * size is 0. - */ -- (nullable void *)allocZeroedMemoryWithSize: (size_t)size - OF_WARN_UNUSED_RESULT; - -/** - * @brief Allocates memory for the specified number of items, initializes it - * with zeros and stores it in the object's memory pool. - * - * It will be free'd automatically when the object is deallocated. - * - * @param size The size of each item to allocate - * @param count The number of items to allocate - * @return A pointer to the allocated memory. May return NULL if the specified - * size or count is 0. - */ -- (nullable void *)allocZeroedMemoryWithSize: (size_t)size - count: (size_t)count - OF_WARN_UNUSED_RESULT; - -/** - * @brief Resizes memory in the object's memory pool to the specified size. - * - * If the pointer is NULL, this is equivalent to allocating memory. - * If the size is 0, this is equivalent to freeing memory. - * - * @param pointer A pointer to the already allocated memory - * @param size The new size for the memory chunk - * @return A pointer to the resized memory chunk - */ -- (nullable void *)resizeMemory: (nullable void *)pointer - size: (size_t)size OF_WARN_UNUSED_RESULT; - -/** - * @brief Resizes memory in the object's memory pool to the specific number of - * items of the specified size. - * - * If the pointer is NULL, this is equivalent to allocating memory. - * If the size or number of items is 0, this is equivalent to freeing memory. - * - * @param pointer A pointer to the already allocated memory - * @param size The size of each item to resize to - * @param count The number of items to resize to - * @return A pointer to the resized memory chunk - */ -- (nullable void *)resizeMemory: (nullable void *)pointer - size: (size_t)size - count: (size_t)count OF_WARN_UNUSED_RESULT; - -/** - * @brief Frees allocated memory and removes it from the object's memory pool. - * - * Does nothing if the pointer is NULL. - * - * @param pointer A pointer to the allocated memory - */ -- (void)freeMemory: (nullable void *)pointer; - /** * @brief Deallocates the object. * * It is automatically called when the retain count reaches zero. * @@ -1327,10 +1236,62 @@ #endif #ifdef __cplusplus extern "C" { #endif +/** + * @brief Allocates memory for the specified number of items. + * + * To free the allocated memory, use `free()`. + * + * Throws @ref OFOutOfMemoryException if allocating failed and + * @ref OFOutOfRangeException if the requested size exceeds the address space. + * + * @param count The number of items to allocate + * @param size The size of each item to allocate + * @return A pointer to the allocated memory. May return NULL if the specified + * size or count is 0. + */ +extern void *_Nullable of_malloc(size_t count, size_t size) + OF_WARN_UNUSED_RESULT; + +/** + * @brief Allocates memory for the specified number of items and initializes it + * with zeros. + * + * To free the allocated memory, use `free()`. + * + * Throws @ref OFOutOfMemoryException if allocating failed and + * @ref OFOutOfRangeException if the requested size exceeds the address space. + * + * @param size The size of each item to allocate + * @param count The number of items to allocate + * @return A pointer to the allocated memory. May return NULL if the specified + * size or count is 0. + */ +extern void *_Nullable of_calloc(size_t count, size_t size) + OF_WARN_UNUSED_RESULT; + +/** + * @brief Resizes memory to the specific number of items of the specified size. + * + * To free the allocated memory, use `free()`. + * + * If the pointer is NULL, this is equivalent to allocating memory. + * If the size or number of items is 0, this is equivalent to freeing memory. + * + * Throws @ref OFOutOfMemoryException if allocating failed and + * @ref OFOutOfRangeException if the requested size exceeds the address space. + * + * @param pointer A pointer to the already allocated memory + * @param size The size of each item to resize to + * @param count The number of items to resize to + * @return A pointer to the resized memory chunk + */ +extern void *_Nullable of_realloc(void *_Nullable pointer, size_t count, + size_t size) OF_WARN_UNUSED_RESULT; + #ifdef OF_APPLE_RUNTIME extern void *_Null_unspecified objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void *_Null_unspecified pool); # ifndef __OBJC2__ extern id _Nullable objc_constructInstance(Class _Nullable class_, Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -84,26 +84,16 @@ struct pre_ivar { int retainCount; #if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) of_spinlock_t retainCountSpinlock; #endif - struct pre_mem *firstMem, *lastMem; -}; - -struct pre_mem { - struct pre_mem *prev, *next; - id owner; }; #define PRE_IVARS_ALIGN ((sizeof(struct pre_ivar) + \ (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1)) #define PRE_IVARS ((struct pre_ivar *)(void *)((char *)self - PRE_IVARS_ALIGN)) -#define PRE_MEM_ALIGN ((sizeof(struct pre_mem) + \ - (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1)) -#define PRE_MEM(mem) ((struct pre_mem *)(void *)((char *)mem - PRE_MEM_ALIGN)) - static struct { Class isa; } allocFailedException; #ifdef OF_AMIGAOS @@ -117,10 +107,63 @@ of_hash_seed_ref(void) { return &of_hash_seed; } #endif + +void * +of_malloc(size_t count, size_t size) +{ + void *pointer; + + if OF_UNLIKELY (count == 0 || size == 0) + return NULL; + + if OF_UNLIKELY (count > SIZE_MAX / size) + @throw [OFOutOfRangeException exception]; + + if OF_UNLIKELY ((pointer = malloc(count * size)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: size]; + + return pointer; +} + +void * +of_calloc(size_t count, size_t size) +{ + void *pointer; + + if OF_UNLIKELY (count == 0 || size == 0) + return NULL; + + /* Not all calloc implementations check for overflow. */ + if OF_UNLIKELY (count > SIZE_MAX / size) + @throw [OFOutOfRangeException exception]; + + if OF_UNLIKELY ((pointer = calloc(count, size)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: size]; + + return pointer; +} + +void * +of_realloc(void *pointer, size_t count, size_t size) +{ + if OF_UNLIKELY (count == 0 || size == 0) + return NULL; + + if OF_UNLIKELY (count > SIZE_MAX / size) + @throw [OFOutOfRangeException exception]; + + if OF_UNLIKELY ((pointer = realloc(pointer, count * size)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: size]; + + return pointer; +} #if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM) static void initRandom(void) { @@ -1035,11 +1078,11 @@ - (bool)isEqual: (id)object { return (object == self); } -- (uint32_t)hash +- (unsigned long)hash { uintptr_t ptr = (uintptr_t)self; uint32_t hash; OF_HASH_INIT(hash); @@ -1059,175 +1102,10 @@ /* Classes containing data should reimplement this! */ return [OFString stringWithFormat: @"<%@>", self.className]; } -- (void *)allocMemoryWithSize: (size_t)size -{ - void *pointer; - struct pre_mem *preMem; - - if OF_UNLIKELY (size == 0) - return NULL; - - if OF_UNLIKELY (size > SIZE_MAX - PRE_IVARS_ALIGN) - @throw [OFOutOfRangeException exception]; - - if OF_UNLIKELY ((pointer = malloc(PRE_MEM_ALIGN + size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - - preMem = pointer; - preMem->owner = self; - preMem->prev = PRE_IVARS->lastMem; - preMem->next = NULL; - - if OF_LIKELY (PRE_IVARS->lastMem != NULL) - PRE_IVARS->lastMem->next = preMem; - - if OF_UNLIKELY (PRE_IVARS->firstMem == NULL) - PRE_IVARS->firstMem = preMem; - - PRE_IVARS->lastMem = preMem; - - return (char *)pointer + PRE_MEM_ALIGN; -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - if OF_UNLIKELY (count > SIZE_MAX / size) - @throw [OFOutOfRangeException exception]; - - return [self allocMemoryWithSize: size * count]; -} - -- (void *)allocZeroedMemoryWithSize: (size_t)size -{ - void *pointer; - struct pre_mem *preMem; - - if OF_UNLIKELY (size == 0) - return NULL; - - if OF_UNLIKELY (size > SIZE_MAX - PRE_IVARS_ALIGN) - @throw [OFOutOfRangeException exception]; - - if OF_UNLIKELY ((pointer = calloc(1, PRE_MEM_ALIGN + size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - - preMem = pointer; - preMem->owner = self; - preMem->prev = PRE_IVARS->lastMem; - - if OF_LIKELY (PRE_IVARS->lastMem != NULL) - PRE_IVARS->lastMem->next = preMem; - - if OF_UNLIKELY (PRE_IVARS->firstMem == NULL) - PRE_IVARS->firstMem = preMem; - - PRE_IVARS->lastMem = preMem; - - return (char *)pointer + PRE_MEM_ALIGN; -} - -- (void *)allocZeroedMemoryWithSize: (size_t)size - count: (size_t)count -{ - if OF_UNLIKELY (count > SIZE_MAX / size) - @throw [OFOutOfRangeException exception]; - - return [self allocZeroedMemoryWithSize: size * count]; -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - void *new; - struct pre_mem *preMem; - - if OF_UNLIKELY (pointer == NULL) - return [self allocMemoryWithSize: size]; - - if OF_UNLIKELY (size == 0) { - [self freeMemory: pointer]; - return NULL; - } - - if OF_UNLIKELY (PRE_MEM(pointer)->owner != self) - @throw [OFMemoryNotPartOfObjectException - exceptionWithPointer: pointer - object: self]; - - if OF_UNLIKELY ((new = realloc(PRE_MEM(pointer), - PRE_MEM_ALIGN + size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - preMem = new; - - if OF_UNLIKELY (preMem != PRE_MEM(pointer)) { - if OF_LIKELY (preMem->prev != NULL) - preMem->prev->next = preMem; - if OF_LIKELY (preMem->next != NULL) - preMem->next->prev = preMem; - - if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer)) - PRE_IVARS->firstMem = preMem; - if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer)) - PRE_IVARS->lastMem = preMem; - } - - return (char *)new + PRE_MEM_ALIGN; -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - if OF_UNLIKELY (pointer == NULL) - return [self allocMemoryWithSize: size - count: count]; - - if OF_UNLIKELY (size == 0 || count == 0) { - [self freeMemory: pointer]; - return NULL; - } - - if OF_UNLIKELY (count > SIZE_MAX / size) - @throw [OFOutOfRangeException exception]; - - return [self resizeMemory: pointer - size: size * count]; -} - -- (void)freeMemory: (void *)pointer -{ - if OF_UNLIKELY (pointer == NULL) - return; - - if OF_UNLIKELY (PRE_MEM(pointer)->owner != self) - @throw [OFMemoryNotPartOfObjectException - exceptionWithPointer: pointer - object: self]; - - if OF_LIKELY (PRE_MEM(pointer)->prev != NULL) - PRE_MEM(pointer)->prev->next = PRE_MEM(pointer)->next; - if OF_LIKELY (PRE_MEM(pointer)->next != NULL) - PRE_MEM(pointer)->next->prev = PRE_MEM(pointer)->prev; - - if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer)) - PRE_IVARS->firstMem = PRE_MEM(pointer)->next; - if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer)) - PRE_IVARS->lastMem = PRE_MEM(pointer)->prev; - - /* To detect double-free */ - PRE_MEM(pointer)->owner = nil; - - free(PRE_MEM(pointer)); -} - - (id)forwardingTargetForSelector: (SEL)selector { return nil; } @@ -1327,29 +1205,12 @@ return true; } - (void)dealloc { - struct pre_mem *iter; - objc_destructInstance(self); - iter = PRE_IVARS->firstMem; - while (iter != NULL) { - struct pre_mem *next = iter->next; - - /* - * We can use owner as a sentinel to prevent exploitation in - * case there is a buffer underflow somewhere. - */ - OF_ENSURE(iter->owner == self); - - free(iter); - - iter = next; - } - free((char *)self - PRE_IVARS_ALIGN); } /* Required to use properties with the Apple runtime */ - (id)copyWithZone: (void *)zone @@ -1371,41 +1232,14 @@ return [(id)self mutableCopy]; } /* - * Those are needed as the root class is the superclass of the root class's - * metaclass and thus instance methods can be sent to class objects as well. + * The following are needed as the root class is the superclass of the root + * class's metaclass and thus instance methods can be sent to class objects as + * well. */ -+ (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void)freeMemory: (void *)pointer -{ - OF_UNRECOGNIZED_SELECTOR -} + (id)retain { return self; } Index: src/OFOptionsParser.m ================================================================== --- src/OFOptionsParser.m +++ src/OFOptionsParser.m @@ -22,11 +22,11 @@ #import "OFArray.h" #import "OFMapTable.h" #import "OFInvalidArgumentException.h" -static uint32_t +static unsigned long stringHash(void *object) { return ((OFString *)object).hash; } @@ -84,16 +84,14 @@ *iter->argumentPtr = nil; count++; } + _options = of_malloc(count + 1, sizeof(*_options)); _longOptions = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions]; - _options = [self - allocMemoryWithSize: sizeof(*_options) - count: count + 1]; for (iter = options, iter2 = _options; iter->shortOption != '\0' || iter->longOption != nil; iter++, iter2++) { iter2->shortOption = iter->shortOption; @@ -144,10 +142,11 @@ - (void)dealloc { of_options_parser_option_t *iter; + free(_options); [_longOptions release]; if (_options != NULL) for (iter = _options; iter->shortOption != '\0' || iter->longOption != nil; @@ -195,16 +194,14 @@ _lastOption = '-'; _index++; if ((pos = [argument rangeOfString: @"="].location) != - OF_NOT_FOUND) { - of_range_t range = of_range(pos + 1, - argument.length - pos - 1); + OF_NOT_FOUND) _argument = [[argument - substringWithRange: range] copy]; - } else + substringFromIndex: pos + 1] copy]; + else pos = argument.length; _lastLongOption = [[argument substringWithRange: of_range(2, pos - 2)] copy]; @@ -253,12 +250,11 @@ if (_index >= _arguments.count) return ':'; argument = [_arguments objectAtIndex: _index]; - argument = [argument substringWithRange: - of_range(_subIndex, argument.length - _subIndex)]; + argument = [argument substringFromIndex: _subIndex]; _argument = [argument copy]; if (iter->isSpecifiedPtr != NULL) *iter->isSpecifiedPtr = true; Index: src/OFPair.m ================================================================== --- src/OFPair.m +++ src/OFPair.m @@ -83,11 +83,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFPollKernelEventObserver.m ================================================================== --- src/OFPollKernelEventObserver.m +++ src/OFPollKernelEventObserver.m @@ -50,12 +50,11 @@ _FDs = [[OFMutableData alloc] initWithItemSize: sizeof(struct pollfd)]; [_FDs addItem: &p]; _maxFD = _cancelFD[0]; - _FDToObject = [self allocMemoryWithSize: sizeof(id) - count: (size_t)_maxFD + 1]; + _FDToObject = of_malloc((size_t)_maxFD + 1, sizeof(id)); } @catch (id e) { [self release]; @throw e; } @@ -63,10 +62,11 @@ } - (void)dealloc { [_FDs release]; + free(_FDToObject); [super dealloc]; } - (void)of_addObject: (id)object @@ -96,13 +96,12 @@ if (!found) { struct pollfd p = { fd, events, 0 }; if (fd > _maxFD) { _maxFD = fd; - _FDToObject = [self resizeMemory: _FDToObject - size: sizeof(id) - count: (size_t)_maxFD + 1]; + _FDToObject = of_realloc(_FDToObject, + (size_t)_maxFD + 1, sizeof(id)); } _FDToObject[fd] = object; [_FDs addItem: &p]; } Index: src/OFSandbox.m ================================================================== --- src/OFSandbox.m +++ src/OFSandbox.m @@ -467,11 +467,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFSecureData.h ================================================================== --- src/OFSecureData.h +++ src/OFSecureData.h @@ -79,31 +79,31 @@ /** * @brief Creates a new, autoreleased OFSecureData with count items of the * specified item size, all set to zero. * - * @param itemSize The size of a single item in the OFSecureData in bytes * @param count The number of zero items the OFSecureData should contain + * @param itemSize The size of a single item in the OFSecureData in bytes * @param allowsSwappableMemory Whether the data may be stored in swappable * memory * @return A new, autoreleased OFSecureData */ -+ (instancetype)dataWithItemSize: (size_t)itemSize - count: (size_t)count - allowsSwappableMemory: (bool)allowsSwappableMemory; ++ (instancetype)dataWithCount: (size_t)count + itemSize: (size_t)itemSize + allowsSwappableMemory: (bool)allowsSwappableMemory; + (instancetype)dataWithItems: (const void *)items count: (size_t)count OF_UNAVAILABLE; + (instancetype)dataWithItems: (const void *)items - itemSize: (size_t)itemSize - count: (size_t)count OF_UNAVAILABLE; + count: (size_t)count + itemSize: (size_t)itemSize OF_UNAVAILABLE; + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; + (instancetype)dataWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path OF_UNAVAILABLE; #endif + (instancetype)dataWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE; @@ -130,26 +130,26 @@ * @param count The number of zero items the OFSecureData should contain * @param allowsSwappableMemory Whether the data may be stored in swappable * memory * @return An initialized OFSecureData */ -- (instancetype)initWithItemSize: (size_t)itemSize - count: (size_t)count - allowsSwappableMemory: (bool)allowsSwappableMemory +- (instancetype)initWithCount: (size_t)count + itemSize: (size_t)itemSize + allowsSwappableMemory: (bool)allowsSwappableMemory OF_DESIGNATED_INITIALIZER; - (instancetype)initWithItems: (const void *)items count: (size_t)count OF_UNAVAILABLE; - (instancetype)initWithItems: (const void *)items - itemSize: (size_t)itemSize - count: (size_t)count OF_UNAVAILABLE; + count: (size_t)count + itemSize: (size_t)itemSize OF_UNAVAILABLE; - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; - (instancetype)initWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path OF_UNAVAILABLE; #endif - (instancetype)initWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE; Index: src/OFSecureData.m ================================================================== --- src/OFSecureData.m +++ src/OFSecureData.m @@ -138,19 +138,24 @@ return page; } } - if ((page = malloc(sizeof(*page))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: sizeof(*page)]; - - if ((page->map = calloc(1, mapSize)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: mapSize]; - - page->page = mapPages(1); + page = of_malloc(1, sizeof(*page)); + @try { + page->map = of_calloc(1, mapSize); + } @catch (id e) { + free(page); + @throw e; + } + @try { + page->page = mapPages(1); + } @catch (id e) { + free(page->map); + free(page); + @throw e; + } of_explicit_memset(page->page, 0, pageSize); # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) lastPage = of_tlskey_get(lastPageKey); # endif @@ -282,25 +287,32 @@ size_t numPages = OF_ROUND_UP_POW2(pageSize, size) / pageSize; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) struct page **preallocatedPages = of_tlskey_get(preallocatedPagesKey); size_t numPreallocatedPages; # endif + size_t i; if (preallocatedPages != NULL) @throw [OFInvalidArgumentException exception]; - preallocatedPages = calloc(numPages, sizeof(struct page)); - if (preallocatedPages == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: numPages * sizeof(struct page)]; - + preallocatedPages = of_calloc(numPages, sizeof(struct page)); # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) of_tlskey_set(preallocatedPagesKey, preallocatedPages); # endif - for (size_t i = 0; i < numPages; i++) - preallocatedPages[i] = addPage(false); + @try { + for (i = 0; i < numPages; i++) + preallocatedPages[i] = addPage(false); + } @catch (id e) { + for (size_t j = 0; j < i; j++) + removePageIfEmpty(preallocatedPages[j]); + + free(preallocatedPages); + preallocatedPages = NULL; + + @throw e; + } numPreallocatedPages = numPages; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) of_tlskey_set(numPreallocatedPagesKey, (void *)(uintptr_t)numPreallocatedPages); @@ -317,17 +329,17 @@ return [[[self alloc] initWithCount: count allowsSwappableMemory: allowsSwappableMemory] autorelease]; } -+ (instancetype)dataWithItemSize: (size_t)itemSize - count: (size_t)count ++ (instancetype)dataWithCount: (size_t)count + itemSize: (size_t)itemSize allowsSwappableMemory: (bool)allowsSwappableMemory { - return [[[self alloc] initWithItemSize: itemSize - count: count - allowsSwappableMemory: allowsSwappableMemory] + return [[[self alloc] initWithCount: count + itemSize: itemSize + allowsSwappableMemory: allowsSwappableMemory] autorelease]; } + (instancetype)dataWithItems: (const void *)items count: (size_t)count @@ -334,12 +346,12 @@ { OF_UNRECOGNIZED_SELECTOR } + (instancetype)dataWithItems: (const void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize { OF_UNRECOGNIZED_SELECTOR } + (instancetype)dataWithItemsNoCopy: (void *)items @@ -348,12 +360,12 @@ { OF_UNRECOGNIZED_SELECTOR } + (instancetype)dataWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { OF_UNRECOGNIZED_SELECTOR } @@ -381,18 +393,18 @@ - (instancetype)initWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory { - return [self initWithItemSize: 1 - count: count - allowsSwappableMemory: allowsSwappableMemory]; + return [self initWithCount: count + itemSize: 1 + allowsSwappableMemory: allowsSwappableMemory]; } -- (instancetype)initWithItemSize: (size_t)itemSize - count: (size_t)count - allowsSwappableMemory: (bool)allowsSwappableMemory +- (instancetype)initWithCount: (size_t)count + itemSize: (size_t)itemSize + allowsSwappableMemory: (bool)allowsSwappableMemory { self = [super init]; @try { #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) @@ -401,12 +413,12 @@ if (count > SIZE_MAX / itemSize) @throw [OFOutOfRangeException exception]; if (allowsSwappableMemory) { - _items = [self allocMemoryWithSize: itemSize - count: count]; + _items = of_malloc(count, itemSize); + _freeWhenDone = true; memset(_items, 0, count * itemSize); #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) } else if (count * itemSize >= pageSize) _items = mapPages(OF_ROUND_UP_POW2(pageSize, count * itemSize) / pageSize); @@ -441,12 +453,12 @@ @throw [OFNotImplementedException exceptionWithSelector: _cmd object: nil]; #endif - _itemSize = itemSize; _count = count; + _itemSize = itemSize; _allowsSwappableMemory = allowsSwappableMemory; } @catch (id e) { [self release]; @throw e; } @@ -459,12 +471,12 @@ { OF_INVALID_INIT_METHOD } - (instancetype)initWithItems: (const void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize { OF_INVALID_INIT_METHOD } - (instancetype)initWithItemsNoCopy: (void *)items @@ -473,12 +485,12 @@ { OF_INVALID_INIT_METHOD } - (instancetype)initWithItemsNoCopy: (void *)items - itemSize: (size_t)itemSize count: (size_t)count + itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { OF_INVALID_INIT_METHOD } @@ -552,12 +564,12 @@ } - (id)copy { OFSecureData *copy = [[OFSecureData alloc] - initWithItemSize: _itemSize - count: _count + initWithCount: _count + itemSize: _itemSize allowsSwappableMemory: _allowsSwappableMemory]; memcpy(copy.mutableItems, _items, _count * _itemSize); return copy; @@ -564,12 +576,12 @@ } - (id)mutableCopy { OFSecureData *copy = [[OFSecureData alloc] - initWithItemSize: _itemSize - count: _count + initWithCount: _count + itemSize: _itemSize allowsSwappableMemory: _allowsSwappableMemory]; memcpy(copy.mutableItems, _items, _count * _itemSize); return copy; Index: src/OFSeekableStream.m ================================================================== --- src/OFSeekableStream.m +++ src/OFSeekableStream.m @@ -53,12 +53,12 @@ offset -= _readBufferLength; offset = [self lowlevelSeekToOffset: offset whence: whence]; - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; return offset; } @end Index: src/OFSelectKernelEventObserver.m ================================================================== --- src/OFSelectKernelEventObserver.m +++ src/OFSelectKernelEventObserver.m @@ -165,19 +165,18 @@ [super removeObjectForWriting: object]; } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { - id const *objects; fd_set readFDs; fd_set writeFDs; struct timeval timeout; int events; #ifdef OF_AMIGAOS ULONG execSignalMask, cancelSignal; #endif - size_t count; + void *pool; if ([self of_processReadBuffers]) return; #ifdef FD_COPY @@ -247,36 +246,36 @@ NULL) == 1); # endif } #endif - objects = _readObjects.objects; - count = _readObjects.count; + pool = objc_autoreleasePoolPush(); - for (size_t i = 0; i < count; i++) { - void *pool = objc_autoreleasePoolPush(); - int fd = [objects[i] fileDescriptorForReading]; + for (id object in + [[_readObjects copy] autorelease]) { + void *pool2 = objc_autoreleasePoolPush(); + int fd = object.fileDescriptorForReading; if (FD_ISSET((of_socket_t)fd, &readFDs) && [_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) - [_delegate objectIsReadyForReading: objects[i]]; + [_delegate objectIsReadyForReading: object]; - objc_autoreleasePoolPop(pool); + objc_autoreleasePoolPop(pool2); } - objects = _writeObjects.objects; - count = _writeObjects.count; - - for (size_t i = 0; i < count; i++) { - void *pool = objc_autoreleasePoolPush(); - int fd = [objects[i] fileDescriptorForWriting]; + for (id object in + [[_writeObjects copy] autorelease]) { + void *pool2 = objc_autoreleasePoolPush(); + int fd = object.fileDescriptorForWriting; if (FD_ISSET((of_socket_t)fd, &writeFDs) && [_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) - [_delegate objectIsReadyForWriting: objects[i]]; + [_delegate objectIsReadyForWriting: object]; - objc_autoreleasePoolPop(pool); + objc_autoreleasePoolPop(pool2); } + + objc_autoreleasePoolPop(pool); } @end Index: src/OFSet.m ================================================================== --- src/OFSet.m +++ src/OFSet.m @@ -296,17 +296,17 @@ return false; return [set isSubsetOfSet: self]; } -- (uint32_t)hash +- (unsigned long)hash { void *pool = objc_autoreleasePoolPush(); - uint32_t hash = 0; + unsigned long hash = 0; for (id object in self) - hash += [object hash]; + hash ^= [object hash]; objc_autoreleasePoolPop(pool); return hash; } Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -90,10 +90,18 @@ @throw e; } return self; } + +- (void)dealloc +{ + free(_readBufferMemory); + free(_writeBuffer); + + [super dealloc]; +} - (bool)lowlevelIsAtEndOfStream { OF_UNRECOGNIZED_SELECTOR } @@ -141,12 +149,11 @@ length: MIN_READ_SIZE]; if (bytesRead > length) { memcpy(buffer, tmp, length); - readBuffer = [self allocMemoryWithSize: - bytesRead - length]; + readBuffer = of_malloc(bytesRead - length, 1); memcpy(readBuffer, tmp + length, bytesRead - length); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength = bytesRead - length; @@ -164,11 +171,11 @@ if (length >= _readBufferLength) { size_t ret = _readBufferLength; memcpy(buffer, _readBuffer, _readBufferLength); - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; return ret; } else { @@ -634,21 +641,18 @@ 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]; - + buffer = of_malloc(count, itemSize); @try { [self readIntoBuffer: buffer exactLength: count * itemSize]; ret = [OFData dataWithItemsNoCopy: buffer - itemSize: itemSize count: count + itemSize: itemSize freeWhenDone: true]; } @catch (id e) { free(buffer); @throw e; } @@ -658,11 +662,11 @@ - (OFData *)readDataUntilEndOfStream { OFMutableData *data = [OFMutableData data]; size_t pageSize = [OFSystemInfo pageSize]; - char *buffer = [self allocMemoryWithSize: pageSize]; + char *buffer = of_malloc(1, pageSize); @try { while (!self.atEndOfStream) { size_t length; @@ -670,11 +674,11 @@ length: pageSize]; [data addItems: buffer count: length]; } } @finally { - [self freeMemory: buffer]; + free(buffer); } [data makeImmutable]; return data; @@ -688,38 +692,38 @@ - (OFString *)readStringWithLength: (size_t)length encoding: (of_string_encoding_t)encoding { OFString *ret; - char *buffer = [self allocMemoryWithSize: length + 1]; + char *buffer = of_malloc(length + 1, 1); buffer[length] = 0; @try { [self readIntoBuffer: buffer exactLength: length]; ret = [OFString stringWithCString: buffer encoding: encoding]; } @finally { - [self freeMemory: buffer]; + free(buffer); } return ret; } - (OFString *)tryReadLineWithEncoding: (of_string_encoding_t)encoding { - size_t pageSize, bufferLength, retLength; - char *retCString, *buffer, *readBuffer; + size_t pageSize, bufferLength; + char *buffer, *readBuffer; OFString *ret; /* Look if there's a line or \0 in our buffer */ if (!_waitingForDelimiter && _readBuffer != NULL) { for (size_t i = 0; i < _readBufferLength; i++) { if OF_UNLIKELY (_readBuffer[i] == '\n' || _readBuffer[i] == '\0') { - retLength = i; + size_t retLength = i; if (i > 0 && _readBuffer[i - 1] == '\r') retLength--; ret = [OFString stringWithCString: _readBuffer @@ -735,14 +739,16 @@ } } /* Read and see if we got a newline or \0 */ pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; + buffer = of_malloc(1, pageSize); @try { if ([self lowlevelIsAtEndOfStream]) { + size_t retLength; + if (_readBuffer == NULL) { _waitingForDelimiter = false; return nil; } @@ -753,11 +759,11 @@ ret = [OFString stringWithCString: _readBuffer encoding: encoding length: retLength]; - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; _waitingForDelimiter = false; return ret; @@ -768,13 +774,12 @@ /* Look if there's a newline or \0 */ for (size_t i = 0; i < bufferLength; i++) { if OF_UNLIKELY (buffer[i] == '\n' || buffer[i] == '\0') { - retLength = _readBufferLength + i; - retCString = [self - allocMemoryWithSize: retLength]; + size_t retLength = _readBufferLength + i; + char *retCString = of_malloc(retLength, 1); if (_readBuffer != NULL) memcpy(retCString, _readBuffer, _readBufferLength); memcpy(retCString + _readBufferLength, @@ -783,54 +788,48 @@ if (retLength > 0 && retCString[retLength - 1] == '\r') retLength--; @try { - char *rcs = retCString; - size_t rl = retLength; - ret = [OFString - stringWithCString: rcs + stringWithCString: retCString encoding: encoding - length: rl]; + length: retLength]; } @catch (id e) { if (bufferLength > 0) { /* * Append data to _readBuffer * to prevent loss of data. */ - readBuffer = [self - allocMemoryWithSize: + readBuffer = of_malloc( _readBufferLength + - bufferLength]; + bufferLength, 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); - [self freeMemory: - _readBufferMemory]; + free(_readBufferMemory); _readBuffer = readBuffer; _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } @throw e; } @finally { - [self freeMemory: retCString]; + free(retCString); } - readBuffer = [self - allocMemoryWithSize: bufferLength - i - 1]; + readBuffer = of_malloc(bufferLength - i - 1, 1); if (readBuffer != NULL) memcpy(readBuffer, buffer + i + 1, bufferLength - i - 1); - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength = bufferLength - i - 1; _waitingForDelimiter = false; return ret; @@ -837,23 +836,23 @@ } } /* There was no newline or \0 */ if (bufferLength > 0) { - readBuffer = [self allocMemoryWithSize: - _readBufferLength + bufferLength]; + readBuffer = of_malloc(_readBufferLength + bufferLength, + 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } } @finally { - [self freeMemory: buffer]; + free(buffer); } _waitingForDelimiter = true; return nil; } @@ -941,12 +940,12 @@ - (OFString *)tryReadTillDelimiter: (OFString *)delimiter encoding: (of_string_encoding_t)encoding { const char *delimiterCString; - size_t j, delimiterLength, pageSize, bufferLength, retLength; - char *retCString, *buffer, *readBuffer; + size_t j, delimiterLength, pageSize, bufferLength; + char *buffer, *readBuffer; OFString *ret; delimiterCString = [delimiter cStringWithEncoding: encoding]; delimiterLength = [delimiter cStringLengthWithEncoding: encoding]; j = 0; @@ -978,11 +977,11 @@ } } /* Read and see if we got a delimiter or \0 */ pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; + buffer = of_malloc(1, pageSize); @try { if ([self lowlevelIsAtEndOfStream]) { if (_readBuffer == NULL) { _waitingForDelimiter = false; @@ -991,11 +990,11 @@ ret = [OFString stringWithCString: _readBuffer encoding: encoding length: _readBufferLength]; - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; _waitingForDelimiter = false; return ret; @@ -1008,17 +1007,19 @@ for (size_t i = 0; i < bufferLength; i++) { if (buffer[i] != delimiterCString[j++]) j = 0; if (j == delimiterLength || buffer[i] == '\0') { + size_t retLength; + char *retCString; + if (buffer[i] == '\0') delimiterLength = 1; retLength = _readBufferLength + i + 1 - delimiterLength; - retCString = [self - allocMemoryWithSize: retLength]; + retCString = of_malloc(retLength, 1); if (_readBuffer != NULL && _readBufferLength <= retLength) memcpy(retCString, _readBuffer, _readBufferLength); @@ -1028,54 +1029,48 @@ if (i >= delimiterLength) memcpy(retCString + _readBufferLength, buffer, i + 1 - delimiterLength); @try { - char *rcs = retCString; - size_t rl = retLength; - ret = [OFString - stringWithCString: rcs + stringWithCString: retCString encoding: encoding - length: rl]; + length: retLength]; } @catch (id e) { if (bufferLength > 0) { /* * Append data to _readBuffer * to prevent loss of data. */ - readBuffer = [self - allocMemoryWithSize: + readBuffer = of_malloc( _readBufferLength + - bufferLength]; + bufferLength, 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); - [self freeMemory: - _readBufferMemory]; + free(_readBufferMemory); _readBuffer = readBuffer; _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } @throw e; } @finally { - [self freeMemory: retCString]; + free(retCString); } - readBuffer = [self allocMemoryWithSize: - bufferLength - i - 1]; + readBuffer = of_malloc(bufferLength - i - 1, 1); if (readBuffer != NULL) memcpy(readBuffer, buffer + i + 1, bufferLength - i - 1); - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength = bufferLength - i - 1; _waitingForDelimiter = false; return ret; @@ -1082,23 +1077,23 @@ } } /* Neither the delimiter nor \0 was found */ if (bufferLength > 0) { - readBuffer = [self allocMemoryWithSize: - _readBufferLength + bufferLength]; + readBuffer = of_malloc(_readBufferLength + bufferLength, + 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } } @finally { - [self freeMemory: buffer]; + free(buffer); } _waitingForDelimiter = true; return nil; } @@ -1135,11 +1130,11 @@ return; [self lowlevelWriteBuffer: _writeBuffer length: _writeBufferLength]; - [self freeMemory: _writeBuffer]; + free(_writeBuffer); _writeBuffer = NULL; _writeBufferLength = 0; } - (size_t)writeBuffer: (const void *)buffer @@ -1156,12 +1151,12 @@ bytesWritten: bytesWritten errNo: 0]; return bytesWritten; } else { - _writeBuffer = [self resizeMemory: _writeBuffer - size: _writeBufferLength + length]; + _writeBuffer = of_realloc(_writeBuffer, + _writeBufferLength + length, 1); memcpy(_writeBuffer + _writeBufferLength, buffer, length); _writeBufferLength += length; return length; } @@ -1339,21 +1334,20 @@ #ifdef OF_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - uint16_t *tmp = [self allocMemoryWithSize: sizeof(uint16_t) - count: count]; + uint16_t *tmp = of_malloc(count, sizeof(uint16_t)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP16(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1370,21 +1364,20 @@ #ifdef OF_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - uint32_t *tmp = [self allocMemoryWithSize: sizeof(uint32_t) - count: count]; + uint32_t *tmp = of_malloc(count, sizeof(uint32_t)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP32(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1401,21 +1394,20 @@ #ifdef OF_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - uint64_t *tmp = [self allocMemoryWithSize: sizeof(uint64_t) - count: count]; + uint64_t *tmp = of_malloc(count, sizeof(uint64_t)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP64(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1432,21 +1424,20 @@ #ifdef OF_FLOAT_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - float *tmp = [self allocMemoryWithSize: sizeof(float) - count: count]; + float *tmp = of_malloc(count, sizeof(float)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP_FLOAT(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1463,21 +1454,20 @@ #ifdef OF_FLOAT_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - double *tmp = [self allocMemoryWithSize: sizeof(double) - count: count]; + double *tmp = of_malloc(count, sizeof(double)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP_DOUBLE(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1534,21 +1524,20 @@ #ifndef OF_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - uint16_t *tmp = [self allocMemoryWithSize: sizeof(uint16_t) - count: count]; + uint16_t *tmp = of_malloc(count, sizeof(uint16_t)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP16(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1565,21 +1554,20 @@ #ifndef OF_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - uint32_t *tmp = [self allocMemoryWithSize: sizeof(uint32_t) - count: count]; + uint32_t *tmp = of_malloc(count, sizeof(uint32_t)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP32(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1596,21 +1584,20 @@ #ifndef OF_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - uint64_t *tmp = [self allocMemoryWithSize: sizeof(uint64_t) - count: count]; + uint64_t *tmp = of_malloc(count, sizeof(uint64_t)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP64(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1627,21 +1614,20 @@ #ifndef OF_FLOAT_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - float *tmp = [self allocMemoryWithSize: sizeof(float) - count: count]; + float *tmp = of_malloc(count, sizeof(float)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP_FLOAT(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1658,21 +1644,20 @@ #ifndef OF_FLOAT_BIG_ENDIAN [self writeBuffer: buffer length: size]; #else - double *tmp = [self allocMemoryWithSize: sizeof(double) - count: count]; + double *tmp = of_malloc(count, sizeof(double)); @try { for (size_t i = 0; i < count; i++) tmp[i] = OF_BSWAP_DOUBLE(buffer[i]); [self writeBuffer: tmp length: size]; } @finally { - [self freeMemory: tmp]; + free(tmp); } #endif return size; } @@ -1732,21 +1717,21 @@ encoding: (of_string_encoding_t)encoding { size_t stringLength = [string cStringLengthWithEncoding: encoding]; char *buffer; - buffer = [self allocMemoryWithSize: stringLength + 1]; + buffer = of_malloc(stringLength + 1, 1); @try { memcpy(buffer, [string cStringWithEncoding: encoding], stringLength); buffer[stringLength] = '\n'; [self writeBuffer: buffer length: stringLength + 1]; } @finally { - [self freeMemory: buffer]; + free(buffer); } return stringLength + 1; } @@ -1887,28 +1872,28 @@ char *readBuffer; if (length > SIZE_MAX - _readBufferLength) @throw [OFOutOfRangeException exception]; - readBuffer = [self allocMemoryWithSize: _readBufferLength + length]; + readBuffer = of_malloc(_readBufferLength + length, 1); memcpy(readBuffer, buffer, length); memcpy(readBuffer + length, _readBuffer, _readBufferLength); - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength += length; } - (void)close { - [self freeMemory: _readBufferMemory]; + free(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; - [self freeMemory: _writeBuffer]; + free(_writeBuffer); _writeBuffer = NULL; _writeBufferLength = 0; _buffersWrites = false; _waitingForDelimiter = false; } @end Index: src/OFString+JSONParsing.m ================================================================== --- src/OFString+JSONParsing.m +++ src/OFString+JSONParsing.m @@ -146,12 +146,11 @@ char delimiter = **pointer; if (++(*pointer) + 1 >= stop) return nil; - if ((buffer = malloc(stop - *pointer)) == NULL) - return nil; + buffer = of_malloc(stop - *pointer, 1); while (*pointer < stop) { /* Parse escape codes */ if (**pointer == '\\') { if (++(*pointer) >= stop) { @@ -293,12 +292,11 @@ parseIdentifier(const char **pointer, const char *stop) { char *buffer; size_t i = 0; - if ((buffer = malloc(stop - *pointer)) == NULL) - return nil; + buffer = of_malloc(stop - *pointer, 1); while (*pointer < stop) { if ((**pointer >= 'a' && **pointer <= 'z') || (**pointer >= 'A' && **pointer <= 'Z') || (**pointer >= '0' && **pointer <= '9') || @@ -384,10 +382,11 @@ /* * It is never possible to end with an identifier, thus we should never * reach stop. */ + free(buffer); return nil; } static inline OFMutableArray * parseArray(const char **pointer, const char *stop, size_t *line, Index: src/OFString+URLEncoding.m ================================================================== --- src/OFString+URLEncoding.m +++ src/OFString+URLEncoding.m @@ -82,18 +82,16 @@ - (OFString *)stringByURLDecoding { void *pool = objc_autoreleasePoolPush(); const char *string = self.UTF8String; size_t length = self.UTF8StringLength; - char *retCString, *retCString2; + char *retCString; char byte = 0; int state = 0; size_t i = 0; - if ((retCString = malloc(length + 1)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: length + 1]; + retCString = of_malloc(length + 1, 1); while (length--) { char c = *string++; switch (state) { @@ -134,14 +132,21 @@ if (state != 0) { free(retCString); @throw [OFInvalidFormatException exception]; } - /* We don't care if it fails, as we only made it smaller. */ - if ((retCString2 = realloc(retCString, i + 1)) == NULL) - retCString2 = retCString; + @try { + retCString = of_realloc(retCString, 1, i + 1); + } @catch (OFOutOfMemoryException *e) { + /* We don't care if it fails, as we only made it smaller. */ + } - return [OFString stringWithUTF8StringNoCopy: retCString2 - length: i - freeWhenDone: true]; + @try { + return [OFString stringWithUTF8StringNoCopy: retCString + length: i + freeWhenDone: true]; + } @catch (id e) { + free(retCString); + @throw e; + } } @end Index: src/OFString+XMLEscaping.m ================================================================== --- src/OFString+XMLEscaping.m +++ src/OFString+XMLEscaping.m @@ -40,17 +40,11 @@ string = self.UTF8String; length = self.UTF8StringLength; j = 0; retLength = length; - - /* - * We can't use allocMemoryWithSize: here as it might be a @"" literal - */ - if ((retCString = malloc(retLength)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: retLength]; + retCString = of_malloc(retLength, 1); for (size_t i = 0; i < length; i++) { switch (string[i]) { case '<': append = "<"; @@ -80,20 +74,17 @@ append = NULL; appendLen = 0; } if (append != NULL) { - char *newRetCString; - - if ((newRetCString = realloc(retCString, - retLength + appendLen)) == NULL) { + @try { + retCString = of_realloc(retCString, 1, + retLength + appendLen); + } @catch (id e) { free(retCString); - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: retLength + - appendLen]; + @throw e; } - retCString = newRetCString; retLength += appendLen - 1; memcpy(retCString + j, append, appendLen); j += appendLen; } else Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -1002,10 +1002,26 @@ * @param string The string to search * @return Whether the string contains the specified string */ - (bool)containsString: (OFString *)string; +/** + * @brief Creates a substring from the specified index to the end. + * + * @param idx The index from where the substring should start, inclusive + * @return The substring from the specified index to the end + */ +- (OFString *)substringFromIndex: (size_t)idx; + +/** + * @brief Creates a substring from the beginning to the specified index. + * + * @param idx The index at which the substring should end, exclusive + * @return The subtring from the beginning to the specified index + */ +- (OFString *)substringToIndex: (size_t)idx; + /** * @brief Creates a substring with the specified range. * * @param range The range of the substring * @return The substring as a new autoreleased OFString Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -834,35 +834,27 @@ } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { - id ret; - - @try { - ret = [self initWithUTF8String: UTF8String]; - } @finally { - if (freeWhenDone) - free(UTF8String); - } + id ret = [self initWithUTF8String: UTF8String]; + + if (freeWhenDone) + free(UTF8String); return ret; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { - id ret; - - @try { - ret = [self initWithUTF8String: UTF8String - length: UTF8StringLength]; - } @finally { - if (freeWhenDone) - free(UTF8String); - } + id ret = [self initWithUTF8String: UTF8String + length: UTF8StringLength]; + + if (freeWhenDone) + free(UTF8String); return ret; } - (instancetype)initWithCString: (const char *)cString @@ -1027,14 +1019,11 @@ * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:]. */ if (SIZE_MAX - (size_t)fileSize < 1) @throw [OFOutOfRangeException exception]; - if ((tmp = malloc((size_t)fileSize + 1)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: (size_t)fileSize]; - + tmp = of_malloc((size_t)fileSize + 1, 1); @try { file = [[OFFile alloc] initWithPath: path mode: @"r"]; [file readIntoBuffer: tmp @@ -1050,15 +1039,20 @@ } @catch (id e) { [self release]; @throw e; } - if (encoding == OF_STRING_ENCODING_UTF_8) - self = [self initWithUTF8StringNoCopy: tmp - length: (size_t)fileSize - freeWhenDone: true]; - else { + if (encoding == OF_STRING_ENCODING_UTF_8) { + @try { + self = [self initWithUTF8StringNoCopy: tmp + length: (size_t)fileSize + freeWhenDone: true]; + } @catch (id e) { + free(tmp); + @throw e; + } + } else { @try { self = [self initWithCString: tmp encoding: encoding length: (size_t)fileSize]; } @finally { @@ -1380,28 +1374,31 @@ } - (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding lossy: (bool)lossy { - OFObject *object = [[[OFObject alloc] init] autorelease]; size_t length = self.length; char *cString; + size_t cStringLength; switch (encoding) { - case OF_STRING_ENCODING_UTF_8:; - size_t cStringLength; - - cString = [object allocMemoryWithSize: (length * 4) + 1]; - - cStringLength = [self of_getCString: cString - maxLength: (length * 4) + 1 - encoding: OF_STRING_ENCODING_UTF_8 - lossy: lossy]; + case OF_STRING_ENCODING_UTF_8: + cString = of_malloc((length * 4) + 1, 1); + + @try { + cStringLength = [self + of_getCString: cString + maxLength: (length * 4) + 1 + encoding: OF_STRING_ENCODING_UTF_8 + lossy: lossy]; + } @catch (id e) { + free(cString); + @throw e; + } @try { - cString = [object resizeMemory: cString - size: cStringLength + 1]; + cString = of_realloc(cString, cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } break; @@ -1416,23 +1413,35 @@ case OF_STRING_ENCODING_CODEPAGE_850: case OF_STRING_ENCODING_CODEPAGE_858: case OF_STRING_ENCODING_MAC_ROMAN: case OF_STRING_ENCODING_KOI8_R: case OF_STRING_ENCODING_KOI8_U: - cString = [object allocMemoryWithSize: length + 1]; + cString = of_malloc(length + 1, 1); - [self of_getCString: cString - maxLength: length + 1 - encoding: encoding - lossy: lossy]; + @try { + cStringLength = [self of_getCString: cString + maxLength: length + 1 + encoding: encoding + lossy: lossy]; + } @catch (id e) { + free(cString); + @throw e; + } break; default: @throw [OFInvalidEncodingException exception]; } - return cString; + @try { + return [[OFData dataWithItemsNoCopy: cString + count: cStringLength + 1 + freeWhenDone: true] items]; + } @catch (id e) { + free(cString); + @throw e; + } } - (const char *)cStringWithEncoding: (of_string_encoding_t)encoding { return [self of_cStringWithEncoding: encoding @@ -1660,11 +1669,11 @@ return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } -- (uint32_t)hash +- (unsigned long)hash { const of_unichar_t *characters = self.characters; size_t length = self.length; uint32_t hash; @@ -1858,14 +1867,11 @@ pool = objc_autoreleasePoolPush(); searchCharacters = string.characters; - if ((characters = malloc(range.length * sizeof(of_unichar_t))) == NULL) - @throw [OFOutOfMemoryException exceptionWithRequestedSize: - range.length * sizeof(of_unichar_t)]; - + characters = of_malloc(range.length, sizeof(of_unichar_t)); @try { [self getCharacters: characters inRange: range]; if (options & OF_STRING_SEARCH_BACKWARDS) { @@ -1929,14 +1935,11 @@ return OF_NOT_FOUND; if (range.length > SIZE_MAX / sizeof(of_unichar_t)) @throw [OFOutOfRangeException exception]; - if ((characters = malloc(range.length * sizeof(of_unichar_t))) == NULL) - @throw [OFOutOfMemoryException exceptionWithRequestedSize: - range.length * sizeof(of_unichar_t)]; - + characters = of_malloc(range.length, sizeof(of_unichar_t)); @try { [self getCharacters: characters inRange: range]; if (options & OF_STRING_SEARCH_BACKWARDS) { @@ -1991,10 +1994,20 @@ objc_autoreleasePoolPop(pool); return false; } + +- (OFString *)substringFromIndex: (size_t)idx +{ + return [self substringWithRange: of_range(idx, self.length - idx)]; +} + +- (OFString *)substringToIndex: (size_t)idx +{ + return [self substringWithRange: of_range(0, idx)]; +} - (OFString *)substringWithRange: (of_range_t)range { void *pool; OFString *ret; @@ -2165,12 +2178,11 @@ bool hasPrefix; if ((prefixLength = prefix.length) > self.length) return false; - tmp = [self allocMemoryWithSize: sizeof(of_unichar_t) - count: prefixLength]; + tmp = of_malloc(prefixLength, sizeof(of_unichar_t)); @try { void *pool = objc_autoreleasePoolPush(); [self getCharacters: tmp inRange: of_range(0, prefixLength)]; @@ -2178,11 +2190,11 @@ hasPrefix = (memcmp(tmp, prefix.characters, prefixLength * sizeof(of_unichar_t)) == 0); objc_autoreleasePoolPop(pool); } @finally { - [self freeMemory: tmp]; + free(tmp); } return hasPrefix; } @@ -2196,12 +2208,11 @@ if ((suffixLength = suffix.length) > self.length) return false; length = self.length; - tmp = [self allocMemoryWithSize: sizeof(of_unichar_t) - count: suffixLength]; + tmp = of_malloc(suffixLength, sizeof(of_unichar_t)); @try { void *pool = objc_autoreleasePoolPush(); [self getCharacters: tmp inRange: of_range(length - suffixLength, @@ -2211,11 +2222,11 @@ hasSuffix = (memcmp(tmp, suffixCharacters, suffixLength * sizeof(of_unichar_t)) == 0); objc_autoreleasePoolPop(pool); } @finally { - [self freeMemory: tmp]; + free(tmp); } return hasSuffix; } @@ -2487,77 +2498,89 @@ return value; } - (const of_unichar_t *)characters { - OFObject *object = [[[OFObject alloc] init] autorelease]; size_t length = self.length; - of_unichar_t *ret; - - ret = [object allocMemoryWithSize: sizeof(of_unichar_t) - count: length]; - [self getCharacters: ret - inRange: of_range(0, length)]; - - return ret; + of_unichar_t *buffer; + + buffer = of_malloc(length, sizeof(of_unichar_t)); + @try { + [self getCharacters: buffer + inRange: of_range(0, length)]; + + return [[OFData dataWithItemsNoCopy: buffer + count: length + itemSize: sizeof(of_unichar_t) + freeWhenDone: true] items]; + } @catch (id e) { + free(buffer); + @throw e; + } } - (const of_char16_t *)UTF16String { return [self UTF16StringWithByteOrder: OF_BYTE_ORDER_NATIVE]; } - (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder { - OFObject *object = [[[OFObject alloc] init] autorelease]; void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; - of_char16_t *ret; + of_char16_t *buffer; size_t j; bool swap = (byteOrder != OF_BYTE_ORDER_NATIVE); /* Allocate memory for the worst case */ - ret = [object allocMemoryWithSize: sizeof(of_char16_t) - count: (length + 1) * 2]; + buffer = of_malloc((length + 1) * 2, sizeof(of_char16_t)); j = 0; for (size_t i = 0; i < length; i++) { of_unichar_t c = characters[i]; - if (c > 0x10FFFF) + if (c > 0x10FFFF) { + free(buffer); @throw [OFInvalidEncodingException exception]; + } if (swap) { if (c > 0xFFFF) { c -= 0x10000; - ret[j++] = OF_BSWAP16(0xD800 | (c >> 10)); - ret[j++] = OF_BSWAP16(0xDC00 | (c & 0x3FF)); + buffer[j++] = OF_BSWAP16(0xD800 | (c >> 10)); + buffer[j++] = OF_BSWAP16(0xDC00 | (c & 0x3FF)); } else - ret[j++] = OF_BSWAP16(c); + buffer[j++] = OF_BSWAP16(c); } else { if (c > 0xFFFF) { c -= 0x10000; - ret[j++] = 0xD800 | (c >> 10); - ret[j++] = 0xDC00 | (c & 0x3FF); + buffer[j++] = 0xD800 | (c >> 10); + buffer[j++] = 0xDC00 | (c & 0x3FF); } else - ret[j++] = c; + buffer[j++] = c; } } - ret[j] = 0; + buffer[j] = 0; @try { - ret = [object resizeMemory: ret - size: sizeof(of_char16_t) - count: j + 1]; + buffer = of_realloc(buffer, j + 1, sizeof(of_char16_t)); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } objc_autoreleasePoolPop(pool); - return ret; + @try { + return [[OFData dataWithItemsNoCopy: buffer + count: j + 1 + itemSize: sizeof(of_char16_t) + freeWhenDone: true] items]; + } @catch (id e) { + free(buffer); + @throw e; + } } - (size_t)UTF16StringLength { const of_unichar_t *characters = self.characters; @@ -2577,25 +2600,31 @@ return [self UTF32StringWithByteOrder: OF_BYTE_ORDER_NATIVE]; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { - OFObject *object = [[[OFObject alloc] init] autorelease]; size_t length = self.length; - of_char32_t *ret; - - ret = [object allocMemoryWithSize: sizeof(of_char32_t) - count: length + 1]; - [self getCharacters: ret - inRange: of_range(0, length)]; - ret[length] = 0; - - if (byteOrder != OF_BYTE_ORDER_NATIVE) - for (size_t i = 0; i < length; i++) - ret[i] = OF_BSWAP32(ret[i]); - - return ret; + of_char32_t *buffer; + + buffer = of_malloc(length + 1, sizeof(of_char32_t)); + @try { + [self getCharacters: buffer + inRange: of_range(0, length)]; + buffer[length] = 0; + + if (byteOrder != OF_BYTE_ORDER_NATIVE) + for (size_t i = 0; i < length; i++) + buffer[i] = OF_BSWAP32(buffer[i]); + + return [[OFData dataWithItemsNoCopy: buffer + count: length + 1 + itemSize: sizeof(of_char32_t) + freeWhenDone: true] items]; + } @catch (id e) { + free(buffer); + @throw e; + } } - (OFData *)dataWithEncoding: (of_string_encoding_t)encoding { void *pool = objc_autoreleasePoolPush(); Index: src/OFSystemInfo.m ================================================================== --- src/OFSystemInfo.m +++ src/OFSystemInfo.m @@ -532,42 +532,44 @@ + (OFString *)CPUVendor { #if defined(OF_X86_64_ASM) || defined(OF_X86_ASM) struct x86_regs regs = x86_cpuid(0, 0); - char buffer[12]; + uint32_t buffer[3]; if (regs.eax == 0) return nil; - memcpy(buffer, ®s.ebx, 4); - memcpy(buffer + 4, ®s.edx, 4); - memcpy(buffer + 8, ®s.ecx, 4); + buffer[0] = regs.ebx; + buffer[1] = regs.edx; + buffer[2] = regs.ecx; - return [OFString stringWithCString: buffer + return [OFString stringWithCString: (char *)buffer encoding: OF_STRING_ENCODING_ASCII length: 12]; #else return nil; #endif } + (OFString *)CPUModel { -#if defined(OF_MACOS) || defined(OF_NETBSD) - char value[256]; - size_t length = sizeof(value); - -# if defined(OF_MACOS) - if (sysctlbyname("machdep.cpu.brand_string", -# elif defined(OF_NETBSD) - if (sysctlbyname("machdep.cpu_brand", -# endif - &value, &length, NULL, 0) != 0) - return nil; - - return [OFString stringWithCString: value +#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM) + uint32_t buffer[12]; + size_t i; + + i = 0; + for (uint32_t eax = 0x80000002; eax <= 0x80000004; eax++) { + struct x86_regs regs = x86_cpuid(eax, 0); + + buffer[i++] = regs.eax; + buffer[i++] = regs.ebx; + buffer[i++] = regs.ecx; + buffer[i++] = regs.edx; + } + + return [OFString stringWithCString: (char *)buffer encoding: OF_STRING_ENCODING_ASCII]; #elif defined(OF_AMIGAOS4) CONST_STRPTR model, version; GetCPUInfoTags(GCIT_ModelString, &model, Index: src/OFTimer.h ================================================================== --- src/OFTimer.h +++ src/OFTimer.h @@ -48,11 +48,11 @@ OFDate *_fireDate; of_time_interval_t _interval; id _target; id _Nullable _object1, _object2, _object3, _object4; SEL _selector; - uint8_t _arguments; + unsigned char _arguments; bool _repeats; #ifdef OF_HAVE_BLOCKS of_timer_block_t _block; #endif bool _valid; Index: src/OFTimer.m ================================================================== --- src/OFTimer.m +++ src/OFTimer.m @@ -326,11 +326,11 @@ selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 object: (id)object4 - arguments: (uint8_t)arguments + arguments: (unsigned char)arguments repeats: (bool)repeats OF_METHOD_FAMILY(init) OF_DIRECT { self = [super init]; Index: src/OFTriple.m ================================================================== --- src/OFTriple.m +++ src/OFTriple.m @@ -97,11 +97,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -848,11 +848,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); @@ -1003,11 +1003,11 @@ objc_autoreleasePoolPop(pool); return @"/"; } if ([path hasSuffix: @"/"]) - path = [path substringWithRange: of_range(0, path.length - 1)]; + path = [path substringToIndex: path.length - 1]; UTF8String = lastComponent = path.UTF8String; length = path.UTF8StringLength; for (size_t i = 1; i <= length; i++) { Index: src/OFUTF8String.h ================================================================== --- src/OFUTF8String.h +++ src/OFUTF8String.h @@ -27,17 +27,17 @@ * Since constant strings don't have `_storage`, they have to allocate * it on the first access. Strings created at runtime just set the * pointer to `&_storage`. */ struct of_string_utf8_ivars { - char *cString; - size_t cStringLength; - bool isUTF8; - size_t length; - bool hashed; - uint32_t hash; - char *_Nullable freeWhenDone; + char *cString; + size_t cStringLength; + bool isUTF8; + size_t length; + bool hashed; + unsigned long hash; + bool freeWhenDone; } *restrict _s; struct of_string_utf8_ivars _storage; } @end Index: src/OFUTF8String.m ================================================================== --- src/OFUTF8String.m +++ src/OFUTF8String.m @@ -26,10 +26,11 @@ #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFArray.h" +#import "OFData.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" @@ -178,12 +179,12 @@ self = [super init]; @try { _s = &_storage; - _s->cString = [self allocMemoryWithSize: 1]; - _s->cString[0] = '\0'; + _s->cString = of_calloc(1, 1); + _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } @@ -244,12 +245,13 @@ cStringLength -= 3; } _s = &_storage; - _s->cString = [self allocMemoryWithSize: cStringLength + 1]; + _s->cString = of_malloc(cStringLength + 1, 1); _s->cStringLength = cStringLength; + _s->freeWhenDone = true; if (encoding == OF_STRING_ENCODING_UTF_8 || encoding == OF_STRING_ENCODING_ASCII) { switch (of_string_utf8_check(cString, cStringLength, &_s->length)) { @@ -291,13 +293,12 @@ if (bytes == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += bytes - 1; - _s->cString = [self - resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, bytes); j += bytes; } @@ -305,15 +306,15 @@ return self; } switch (encoding) { -#define CASE(encoding, var) \ - case encoding: \ - table = var; \ - tableOffset = var##_offset; \ - break; +#define CASE(encoding, var) \ + case encoding: \ + table = var; \ + tableOffset = var##_offset; \ + break; #ifdef HAVE_ISO_8859_2 CASE(OF_STRING_ENCODING_ISO_8859_2, of_iso_8859_2_table) #endif #ifdef HAVE_ISO_8859_3 CASE(OF_STRING_ENCODING_ISO_8859_3, of_iso_8859_3_table) @@ -372,13 +373,12 @@ if (byteLength == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += byteLength - 1; - _s->cString = [self - resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, byteLength); j += byteLength; } @@ -402,41 +402,33 @@ - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { - @try { - self = [super init]; - } @catch (id e) { - if (freeWhenDone) - free(UTF8String); - @throw e; - } + self = [super init]; @try { _s = &_storage; - if (freeWhenDone) - _s->freeWhenDone = UTF8String; - if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } - _s->cString = (char *)UTF8String; - _s->cStringLength = UTF8StringLength; - switch (of_string_utf8_check(UTF8String, UTF8StringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } + + _s->cString = (char *)UTF8String; + _s->cStringLength = UTF8StringLength; + _s->freeWhenDone = freeWhenDone; } @catch (id e) { [self release]; @throw e; } @@ -458,12 +450,13 @@ else _s->isUTF8 = true; _s->length = string.length; - _s->cString = [self allocMemoryWithSize: _s->cStringLength + 1]; + _s->cString = of_malloc(_s->cStringLength + 1, 1); memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1); + _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } @@ -478,12 +471,13 @@ @try { size_t j; _s = &_storage; - _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; + _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { size_t len = of_string_utf8_encode(characters[i], _s->cString + j); @@ -499,12 +493,11 @@ _s->cString[j] = '\0'; _s->cStringLength = j; @try { - _s->cString = [self resizeMemory: _s->cString - size: j + 1]; + _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @@ -534,12 +527,13 @@ } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; - _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; + _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { of_unichar_t character = (swap ? OF_BSWAP16(string[i]) : string[i]); @@ -584,12 +578,11 @@ _s->cString[j] = '\0'; _s->cStringLength = j; @try { - _s->cString = [self resizeMemory: _s->cString - size: j + 1]; + _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @@ -619,12 +612,13 @@ } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; - _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; + _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = of_string_utf8_encode( @@ -651,12 +645,11 @@ _s->cString[j] = '\0'; _s->cStringLength = j; @try { - _s->cString = [self resizeMemory: _s->cString - size: j + 1]; + _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @@ -694,13 +687,13 @@ break; case -1: @throw [OFInvalidEncodingException exception]; } - _s->cString = [self - allocMemoryWithSize: cStringLength + 1]; + _s->cString = of_malloc(cStringLength + 1, 1); memcpy(_s->cString, tmp, cStringLength + 1); + _s->freeWhenDone = true; } @finally { free(tmp); } } @catch (id e) { [self release]; @@ -710,12 +703,12 @@ return self; } - (void)dealloc { - if (_s != NULL && _s->freeWhenDone != NULL) - free(_s->freeWhenDone); + if (_s != NULL && _s->freeWhenDone) + free(_s->cString); [super dealloc]; } - (size_t)getCString: (char *)cString @@ -927,11 +920,11 @@ #endif return OF_ORDERED_SAME; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; if (_s->hashed) return _s->hash; @@ -1160,67 +1153,65 @@ return array; } - (const of_unichar_t *)characters { - OFObject *object = [[[OFObject alloc] init] autorelease]; - of_unichar_t *ret; - size_t i, j; - - ret = [object allocMemoryWithSize: sizeof(of_unichar_t) - count: _s->length]; - - i = j = 0; + of_unichar_t *buffer = of_malloc(_s->length, sizeof(of_unichar_t)); + size_t i = 0, j = 0; while (i < _s->cStringLength) { of_unichar_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen <= 0 || c > 0x10FFFF) + if (cLen <= 0 || c > 0x10FFFF) { + free(buffer); @throw [OFInvalidEncodingException exception]; + } - ret[j++] = c; + buffer[j++] = c; i += cLen; } - return ret; + return [[OFData dataWithItemsNoCopy: buffer + count: _s->length + itemSize: sizeof(of_unichar_t) + freeWhenDone: true] items]; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { - OFObject *object = [[[OFObject alloc] init] autorelease]; - of_char32_t *ret; - size_t i, j; - - ret = [object allocMemoryWithSize: sizeof(of_unichar_t) - count: _s->length + 1]; - - i = j = 0; + of_char32_t *buffer = of_malloc(_s->length + 1, sizeof(of_char32_t)); + size_t i = 0, j = 0; while (i < _s->cStringLength) { - of_unichar_t c; + of_char32_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen <= 0 || c > 0x10FFFF) + if (cLen <= 0 || c > 0x10FFFF) { + free(buffer); @throw [OFInvalidEncodingException exception]; + } if (byteOrder != OF_BYTE_ORDER_NATIVE) - ret[j++] = OF_BSWAP32(c); + buffer[j++] = OF_BSWAP32(c); else - ret[j++] = c; + buffer[j++] = c; i += cLen; } - ret[j] = 0; + buffer[j] = 0; - return ret; + return [[OFData dataWithItemsNoCopy: buffer + count: _s->length + 1 + itemSize: sizeof(of_char32_t) + freeWhenDone: true] items]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block { Index: src/OFValue.m ================================================================== --- src/OFValue.m +++ src/OFValue.m @@ -181,18 +181,16 @@ if (strcmp([object objCType], objCType) != 0) return false; size = of_sizeof_type_encoding(objCType); - if ((value = malloc(size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - - if ((otherValue = malloc(size)) == NULL) { + value = of_malloc(1, size); + @try { + otherValue = of_malloc(1, size); + } @catch (id e) { free(value); - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; + @throw e; } @try { [self getValue: value size: size]; @@ -206,20 +204,17 @@ } return ret; } -- (uint32_t)hash +- (unsigned long)hash { size_t size = of_sizeof_type_encoding(self.objCType); unsigned char *value; uint32_t hash; - if ((value = malloc(size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - + value = of_malloc(1, size); @try { [self getValue: value size: size]; OF_HASH_INIT(hash); @@ -316,14 +311,11 @@ OFMutableString *ret = [OFMutableString stringWithString: @" UINT32_MAX) @throw [OFOutOfRangeException exception]; - UTF16 = [self allocMemoryWithSize: sizeof(of_char16_t) - count: length]; + UTF16 = of_malloc(length, sizeof(of_char16_t)); @try { DWORD UTF16Len; OFMutableData *rest = nil; size_t i = 0; @@ -258,11 +257,11 @@ if (rest != nil) [self unreadFromBuffer: rest.items length: rest.count]; } @finally { - [self freeMemory: UTF16]; + free(UTF16); } objc_autoreleasePoolPop(pool); return j; @@ -363,12 +362,11 @@ _incompleteUTF8SurrogateLen = 0; i += toCopy; } - tmp = [self allocMemoryWithSize: sizeof(of_char16_t) - count: length * 2]; + tmp = of_malloc(length * 2, sizeof(of_char16_t)); @try { DWORD bytesWritten; while (i < length) { of_unichar_t c; @@ -443,11 +441,11 @@ exceptionWithObject: self requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: 0]; } @finally { - [self freeMemory: tmp]; + free(tmp); } /* * We do not count in bytes when writing to the Win32 console. But * since any incomplete write is an exception here anyway, we can just Index: src/OFXMLAttribute.m ================================================================== --- src/OFXMLAttribute.m +++ src/OFXMLAttribute.m @@ -138,11 +138,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFXMLCDATA.m ================================================================== --- src/OFXMLCDATA.m +++ src/OFXMLCDATA.m @@ -86,11 +86,11 @@ CDATA = object; return ([CDATA->_CDATA isEqual: _CDATA]); } -- (uint32_t)hash +- (unsigned long)hash { return _CDATA.hash; } - (OFString *)stringValue Index: src/OFXMLCharacters.m ================================================================== --- src/OFXMLCharacters.m +++ src/OFXMLCharacters.m @@ -86,11 +86,11 @@ characters = object; return ([characters->_characters isEqual: _characters]); } -- (uint32_t)hash +- (unsigned long)hash { return _characters.hash; } - (OFString *)stringValue Index: src/OFXMLComment.m ================================================================== --- src/OFXMLComment.m +++ src/OFXMLComment.m @@ -88,11 +88,11 @@ comment = object; return ([comment->_comment isEqual: _comment]); } -- (uint32_t)hash +- (unsigned long)hash { return _comment.hash; } - (OFString *)stringValue @@ -114,21 +114,20 @@ level: (unsigned int)level { OFString *ret; if (indentation > 0 && level > 0) { - char *whitespaces = [self allocMemoryWithSize: - (level * indentation) + 1]; + char *whitespaces = of_malloc((level * indentation) + 1, 1); memset(whitespaces, ' ', level * indentation); whitespaces[level * indentation] = 0; @try { ret = [OFString stringWithFormat: @"%s", whitespaces, _comment]; } @finally { - [self freeMemory: whitespaces]; + free(whitespaces); } } else ret = [OFString stringWithFormat: @"", _comment]; return ret; Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -46,13 +46,10 @@ _references_to_categories_of_OFXMLElement(void) { _OFXMLElement_Serialization_reference = 1; } -static Class charactersClass = Nil; -static Class CDATAClass = Nil; - @interface OFXMLElementElementBuilderDelegate: OFObject { @public OFXMLElement *_element; @@ -77,18 +74,10 @@ @implementation OFXMLElement @synthesize name = _name, namespace = _namespace; @synthesize defaultNamespace = _defaultNamespace; -+ (void)initialize -{ - if (self == [OFXMLElement class]) { - charactersClass = [OFXMLCharacters class]; - CDATAClass = [OFXMLCDATA class]; - } -} - + (instancetype)elementWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } @@ -424,11 +413,11 @@ return ret; } - (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent - namespaces: (OFDictionary *)allNamespaces + namespaces: (OFDictionary *)allNS indentation: (unsigned int)indentation level: (unsigned int)level OF_DIRECT { void *pool; char *cString; @@ -437,33 +426,33 @@ OFString *ret; OFString *defaultNS; pool = objc_autoreleasePoolPush(); - parentPrefix = [allNamespaces objectForKey: + parentPrefix = [allNS objectForKey: (parent != nil && parent->_namespace != nil ? parent->_namespace : (OFString *)@"")]; /* Add the namespaces of the current element */ - if (allNamespaces != nil) { + if (allNS != nil) { OFEnumerator *keyEnumerator = [_namespaces keyEnumerator]; OFEnumerator *objectEnumerator = [_namespaces objectEnumerator]; OFMutableDictionary *tmp; OFString *key, *object; - tmp = [[allNamespaces mutableCopy] autorelease]; + tmp = [[allNS mutableCopy] autorelease]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [tmp setObject: object forKey: key]; - allNamespaces = tmp; + allNS = tmp; } else - allNamespaces = _namespaces; + allNS = _namespaces; - prefix = [allNamespaces objectForKey: + prefix = [allNS objectForKey: (_namespace != nil ? _namespace : (OFString *)@"")]; if (parent != nil && parent->_namespace != nil && parentPrefix == nil) defaultNS = parent->_namespace; else if (parent != nil && parent->_defaultNamespace != nil) @@ -471,198 +460,178 @@ else defaultNS = _defaultNamespace; i = 0; length = _name.UTF8StringLength + 3 + (level * indentation); - cString = [self allocMemoryWithSize: length]; - - memset(cString + i, ' ', level * indentation); - i += level * indentation; - - /* Start of tag */ - cString[i++] = '<'; - - if (prefix != nil && ![_namespace isEqual: defaultNS]) { - length += prefix.UTF8StringLength + 1; - @try { - cString = [self resizeMemory: cString - size: length]; - } @catch (id e) { - [self freeMemory: cString]; - @throw e; - } - - memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); - i += prefix.UTF8StringLength; - cString[i++] = ':'; - } - - memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); - i += _name.UTF8StringLength; - - /* xmlns if necessary */ - if (prefix == nil && ((_namespace != nil && - ![_namespace isEqual: defaultNS]) || - (_namespace == nil && defaultNS != nil))) { - length += _namespace.UTF8StringLength + 9; - @try { - cString = [self resizeMemory: cString - size: length]; - } @catch (id e) { - [self freeMemory: cString]; - @throw e; - } - - memcpy(cString + i, " xmlns='", 8); - i += 8; - memcpy(cString + i, _namespace.UTF8String, - _namespace.UTF8StringLength); - i += _namespace.UTF8StringLength; - cString[i++] = '\''; - } - - /* Attributes */ - for (OFXMLAttribute *attribute in _attributes) { - void *pool2 = objc_autoreleasePoolPush(); - const char *attributeNameCString = attribute->_name.UTF8String; - size_t attributeNameLength = attribute->_name.UTF8StringLength; - OFString *attributePrefix = nil; - OFString *tmp = attribute.stringValue.stringByXMLEscaping; - char delimiter = (attribute->_useDoubleQuotes ? '"' : '\''); - - if (attribute->_namespace != nil && - (attributePrefix = [allNamespaces objectForKey: - attribute->_namespace]) == nil) - @throw [OFUnboundNamespaceException - exceptionWithNamespace: [attribute namespace] - element: self]; - - length += attributeNameLength + (attributePrefix != nil - ? attributePrefix.UTF8StringLength + 1 : 0) + - tmp.UTF8StringLength + 4; - - @try { - cString = [self resizeMemory: cString - size: length]; - } @catch (id e) { - [self freeMemory: cString]; - @throw e; - } - - cString[i++] = ' '; - if (attributePrefix != nil) { - memcpy(cString + i, attributePrefix.UTF8String, - attributePrefix.UTF8StringLength); - i += attributePrefix.UTF8StringLength; - cString[i++] = ':'; - } - memcpy(cString + i, attributeNameCString, attributeNameLength); - i += attributeNameLength; - cString[i++] = '='; - cString[i++] = delimiter; - memcpy(cString + i, tmp.UTF8String, tmp.UTF8StringLength); - i += tmp.UTF8StringLength; - cString[i++] = delimiter; - - objc_autoreleasePoolPop(pool2); - } - - /* Children */ - if (_children != nil) { - OFMutableData *tmp = [OFMutableData data]; - bool indent; - - if (indentation > 0) { - indent = true; - - for (OFXMLNode *child in _children) { - if ([child isKindOfClass: charactersClass] || - [child isKindOfClass: CDATAClass]) { - indent = false; - break; - } - } - } else - indent = false; - - for (OFXMLNode *child in _children) { - OFString *childString; - unsigned int ind = (indent ? indentation : 0); - - if (ind) - [tmp addItem: "\n"]; - - if ([child isKindOfClass: [OFXMLElement class]]) - childString = [(OFXMLElement *)child - of_XMLStringWithParent: self - namespaces: allNamespaces - indentation: ind - level: level + 1]; - else - childString = [child - XMLStringWithIndentation: ind - level: level + 1]; - - [tmp addItems: childString.UTF8String - count: childString.UTF8StringLength]; - } - - if (indent) - [tmp addItem: "\n"]; - - length += tmp.count + _name.UTF8StringLength + 2 + - (indent ? level * indentation : 0); - @try { - cString = [self resizeMemory: cString - size: length]; - } @catch (id e) { - [self freeMemory: cString]; - @throw e; - } - - cString[i++] = '>'; - - memcpy(cString + i, tmp.items, tmp.count); - i += tmp.count; - - if (indent) { - memset(cString + i, ' ', level * indentation); - i += level * indentation; - } - - cString[i++] = '<'; - cString[i++] = '/'; - if (prefix != nil) { - length += prefix.UTF8StringLength + 1; - @try { - cString = [self resizeMemory: cString - size: length]; - } @catch (id e) { - [self freeMemory: cString]; - @throw e; - } + cString = of_malloc(length, 1); + + @try { + memset(cString + i, ' ', level * indentation); + i += level * indentation; + + /* Start of tag */ + cString[i++] = '<'; + + if (prefix != nil && ![_namespace isEqual: defaultNS]) { + length += prefix.UTF8StringLength + 1; + cString = of_realloc(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); i += prefix.UTF8StringLength; cString[i++] = ':'; } + memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; - } else - cString[i++] = '/'; - - cString[i++] = '>'; - assert(i == length); - - objc_autoreleasePoolPop(pool); - - @try { + + /* xmlns if necessary */ + if (prefix == nil && ((_namespace != nil && + ![_namespace isEqual: defaultNS]) || + (_namespace == nil && defaultNS != nil))) { + length += _namespace.UTF8StringLength + 9; + cString = of_realloc(cString, length, 1); + + memcpy(cString + i, " xmlns='", 8); + i += 8; + memcpy(cString + i, _namespace.UTF8String, + _namespace.UTF8StringLength); + i += _namespace.UTF8StringLength; + cString[i++] = '\''; + } + + /* Attributes */ + for (OFXMLAttribute *attribute in _attributes) { + void *pool2 = objc_autoreleasePoolPush(); + const char *attributeNameCString = + attribute->_name.UTF8String; + size_t attributeNameLength = + attribute->_name.UTF8StringLength; + OFString *attributePrefix = nil; + OFString *tmp = + attribute.stringValue.stringByXMLEscaping; + char delimiter = (attribute->_useDoubleQuotes + ? '"' : '\''); + + if (attribute->_namespace != nil && + (attributePrefix = [allNS objectForKey: + attribute->_namespace]) == nil) + @throw [OFUnboundNamespaceException + exceptionWithNamespace: attribute.namespace + element: self]; + + length += attributeNameLength + (attributePrefix != nil + ? attributePrefix.UTF8StringLength + 1 : 0) + + tmp.UTF8StringLength + 4; + cString = of_realloc(cString, length, 1); + + cString[i++] = ' '; + if (attributePrefix != nil) { + memcpy(cString + i, attributePrefix.UTF8String, + attributePrefix.UTF8StringLength); + i += attributePrefix.UTF8StringLength; + cString[i++] = ':'; + } + memcpy(cString + i, attributeNameCString, + attributeNameLength); + i += attributeNameLength; + cString[i++] = '='; + cString[i++] = delimiter; + memcpy(cString + i, tmp.UTF8String, + tmp.UTF8StringLength); + i += tmp.UTF8StringLength; + cString[i++] = delimiter; + + objc_autoreleasePoolPop(pool2); + } + + /* Children */ + if (_children != nil) { + OFMutableData *tmp = [OFMutableData data]; + bool indent; + + if (indentation > 0) { + indent = true; + + for (OFXMLNode *child in _children) { + if ([child isKindOfClass: + [OFXMLCharacters class]] || + [child isKindOfClass: + [OFXMLCDATA class]]) { + indent = false; + break; + } + } + } else + indent = false; + + for (OFXMLNode *child in _children) { + OFString *childString; + unsigned int ind = (indent ? indentation : 0); + + if (ind) + [tmp addItem: "\n"]; + + if ([child isKindOfClass: [OFXMLElement class]]) + childString = [(OFXMLElement *)child + of_XMLStringWithParent: self + namespaces: allNS + indentation: ind + level: level + 1]; + else + childString = [child + XMLStringWithIndentation: ind + level: level + + 1]; + + [tmp addItems: childString.UTF8String + count: childString.UTF8StringLength]; + } + + if (indent) + [tmp addItem: "\n"]; + + length += tmp.count + _name.UTF8StringLength + 2 + + (indent ? level * indentation : 0); + cString = of_realloc(cString, length, 1); + + cString[i++] = '>'; + + memcpy(cString + i, tmp.items, tmp.count); + i += tmp.count; + + if (indent) { + memset(cString + i, ' ', level * indentation); + i += level * indentation; + } + + cString[i++] = '<'; + cString[i++] = '/'; + if (prefix != nil) { + length += prefix.UTF8StringLength + 1; + cString = of_realloc(cString, length, 1); + + memcpy(cString + i, prefix.UTF8String, + prefix.UTF8StringLength); + i += prefix.UTF8StringLength; + cString[i++] = ':'; + } + memcpy(cString + i, _name.UTF8String, + _name.UTF8StringLength); + i += _name.UTF8StringLength; + } else + cString[i++] = '/'; + + cString[i++] = '>'; + assert(i == length); + + objc_autoreleasePoolPop(pool); + ret = [OFString stringWithUTF8String: cString length: length]; } @finally { - [self freeMemory: cString]; + free(cString); } return ret; } - (OFString *)XMLString @@ -1064,11 +1033,11 @@ return false; return true; } -- (uint32_t)hash +- (unsigned long)hash { uint32_t hash; OF_HASH_INIT(hash); Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -276,11 +276,11 @@ } - (void)parseStream: (OFStream *)stream { size_t pageSize = [OFSystemInfo pageSize]; - char *buffer = [self allocMemoryWithSize: pageSize]; + char *buffer = of_malloc(1, pageSize); @try { while (!stream.atEndOfStream) { size_t length = [stream readIntoBuffer: buffer length: pageSize]; @@ -287,11 +287,11 @@ [self parseBuffer: buffer length: length]; } } @finally { - [self freeMemory: buffer]; + free(buffer); } } #ifdef OF_HAVE_FILES - (void)parseFile: (OFString *)path @@ -414,11 +414,11 @@ if (!self->_acceptProlog) return false; self->_acceptProlog = false; - pi = [pi substringWithRange: of_range(3, pi.length - 3)]; + pi = [pi substringFromIndex: 3]; pi = pi.stringByDeletingEnclosingWhitespaces; cString = pi.UTF8String; length = pi.UTF8StringLength; Index: src/OFXMLProcessingInstructions.m ================================================================== --- src/OFXMLProcessingInstructions.m +++ src/OFXMLProcessingInstructions.m @@ -89,11 +89,11 @@ return [processingInstructions->_processingInstructions isEqual: _processingInstructions]; } -- (uint32_t)hash +- (unsigned long)hash { return _processingInstructions.hash; } - (OFString *)stringValue @@ -115,20 +115,19 @@ level: (unsigned int)level { OFString *ret; if (indentation > 0 && level > 0) { - char *whitespaces = [self allocMemoryWithSize: - (level * indentation) + 1]; + char *whitespaces = of_malloc((level * indentation) + 1, 1); memset(whitespaces, ' ', level * indentation); whitespaces[level * indentation] = 0; @try { ret = [OFString stringWithFormat: @"%s", whitespaces, _processingInstructions]; } @finally { - [self freeMemory: whitespaces]; + free(whitespaces); } } else ret = [OFString stringWithFormat: @"", _processingInstructions]; Index: src/condition.h ================================================================== --- src/condition.h +++ src/condition.h @@ -41,11 +41,11 @@ #elif defined(OF_AMIGAOS) # include typedef struct { struct of_condition_waiting_task { struct Task *task; - uint8_t sigBit; + unsigned char sigBit; struct of_condition_waiting_task *next; } *waitingTasks; } of_condition_t; #endif Index: src/exceptions/OFAllocFailedException.m ================================================================== --- src/exceptions/OFAllocFailedException.m +++ src/exceptions/OFAllocFailedException.m @@ -34,39 +34,10 @@ - (instancetype)init { OF_INVALID_INIT_METHOD } -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryForNItems: (size_t)nitems - withSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - toSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - toNItems: (size_t)nitems - withSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)ptr -{ - OF_UNRECOGNIZED_SELECTOR -} - - (instancetype)retain { return self; } Index: src/exceptions/OFHTTPRequestFailedException.m ================================================================== --- src/exceptions/OFHTTPRequestFailedException.m +++ src/exceptions/OFHTTPRequestFailedException.m @@ -64,9 +64,9 @@ - (OFString *)description { const char *method = of_http_request_method_to_string(_request.method); return [OFString stringWithFormat: - @"An HTTP %s request with URL %@ failed with code %d!", method, + @"An HTTP %s request with URL %@ failed with code %hd!", method, _request.URL, _response.statusCode]; } @end Index: src/huffman_tree.m ================================================================== --- src/huffman_tree.m +++ src/huffman_tree.m @@ -28,14 +28,11 @@ static struct of_huffman_tree * newTree(void) { struct of_huffman_tree *tree; - if ((tree = malloc(sizeof(*tree))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: sizeof(*tree)]; - + tree = of_malloc(1, sizeof(*tree)); tree->leaves[0] = tree->leaves[1] = NULL; tree->value = 0xFFFF; return tree; } @@ -70,24 +67,14 @@ @try { for (uint16_t i = 0; i < count; i++) { uint_fast8_t length = lengths[i]; if OF_UNLIKELY (length > maxBit) { - size_t size = (length + 1) * sizeof(uint16_t); - uint16_t *new; - - if ((new = realloc(lengthCount, size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - - lengthCount = new; - - if ((new = realloc(nextCode, size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - - nextCode = new; + lengthCount = of_realloc(lengthCount, + length + 1, sizeof(uint16_t)); + nextCode = of_realloc(nextCode, + length + 1, sizeof(uint16_t)); for (uint_fast8_t j = maxBit + 1; j <= length; j++) { lengthCount[j] = 0; nextCode[j] = 0; Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -812,11 +812,11 @@ hash ^= (hash >> 11); \ hash += (hash << 15); \ } #define OF_HASH_ADD_HASH(hash, other) \ { \ - uint32_t otherCopy = other; \ + uint32_t otherCopy = (uint32_t)other; \ OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF); \ OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF); \ OF_HASH_ADD(hash, (otherCopy >> 8) & 0xFF); \ OF_HASH_ADD(hash, otherCopy & 0xFF); \ } Index: src/of_strptime.h ================================================================== --- src/of_strptime.h +++ src/of_strptime.h @@ -30,11 +30,11 @@ #ifdef __cplusplus extern "C" { #endif extern const char *_Nullable of_strptime(const char *buf, const char *fmt, - struct tm *tm, int16_t *_Nullable tz); + struct tm *tm, short *_Nullable tz); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/of_strptime.m ================================================================== --- src/of_strptime.m +++ src/of_strptime.m @@ -22,11 +22,11 @@ #include #import "macros.h" const char * -of_strptime(const char *buffer, const char *format, struct tm *tm, int16_t *tz) +of_strptime(const char *buffer, const char *format, struct tm *tm, short *tz) { enum { SEARCH_CONVERSION_SPECIFIER, IN_CONVERSION_SPECIFIER } state = SEARCH_CONVERSION_SPECIFIER; @@ -179,14 +179,14 @@ return NULL; if (tz == NULL) break; - *tz = (((int16_t)b[1] - '0') * 600 + - ((int16_t)b[2] - '0') * 60 + - ((int16_t)b[3] - '0') * 10 + - ((int16_t)b[4] - '0')) * + *tz = (((short)b[1] - '0') * 600 + + ((short)b[2] - '0') * 60 + + ((short)b[3] - '0') * 10 + + ((short)b[4] - '0')) * (b[0] == '-' ? -1 : 1); j += 5; } else if (buffer[j] == 'Z') { if (tz != NULL) Index: src/pbkdf2.h ================================================================== --- src/pbkdf2.h +++ src/pbkdf2.h @@ -33,11 +33,11 @@ /** * @brief The parameters for @ref of_pbkdf2. */ typedef struct of_pbkdf2_parameters_t { /** @brief The HMAC to use to derive a key. */ - OFHMAC *HMAC; + __unsafe_unretained OFHMAC *HMAC; /** @brief The number of iterations to perform. */ size_t iterations; /** @brief The salt to derive a key with. */ const unsigned char *salt; /** @brief The length of the salt. */ Index: src/platform/amiga/OFString+PathAdditions.m ================================================================== --- src/platform/amiga/OFString+PathAdditions.m +++ src/platform/amiga/OFString+PathAdditions.m @@ -125,12 +125,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } - ret = [fileName substringWithRange: - of_range(pos + 1, fileName.length - pos - 1)]; + ret = [fileName substringFromIndex: pos + 1]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -185,11 +184,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } - fileName = [fileName substringWithRange: of_range(0, pos)]; + fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; @@ -303,16 +302,16 @@ - (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost { OFString *path = self; if (path.length > 1 && [path hasSuffix: @"/"]) - path = [path substringWithRange: of_range(0, path.length - 1)]; + path = [path substringToIndex: path.length - 1]; OFMutableArray OF_GENERIC(OFString *) *components; size_t count; - path = [path substringWithRange: of_range(1, path.length - 1)]; + path = [path substringFromIndex: 1]; components = [[[path componentsSeparatedByString: @"/"] mutableCopy] autorelease]; count = components.count; for (size_t i = 0; i < count; i++) { Index: src/platform/libfat/OFString+PathAdditions.m ================================================================== --- src/platform/libfat/OFString+PathAdditions.m +++ src/platform/libfat/OFString+PathAdditions.m @@ -159,12 +159,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } - ret = [fileName substringWithRange: - of_range(pos + 1, fileName.length - pos - 1)]; + ret = [fileName substringFromIndex: pos + 1]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -230,11 +229,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } - fileName = [fileName substringWithRange: of_range(0, pos)]; + fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; @@ -332,15 +331,15 @@ - (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost { OFString *path = self; if (path.length > 1 && [path hasSuffix: @"/"]) - path = [path substringWithRange: of_range(0, path.length - 1)]; + path = [path substringToIndex: path.length - 1]; - return [path substringWithRange: of_range(1, path.length - 1)]; + return [path substringFromIndex: 1]; } - (OFString *)of_pathComponentToURLPathComponent { return self; } @end Index: src/platform/posix/OFProcess.m ================================================================== --- src/platform/posix/OFProcess.m +++ src/platform/posix/OFProcess.m @@ -127,11 +127,11 @@ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *path; - char **argv; + char **argv, **env = NULL; _pid = -1; _readPipe[0] = _writePipe[1] = -1; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @@ -142,12 +142,11 @@ [self of_getArgv: &argv forProgramName: programName andArguments: arguments]; @try { - char **env = [self - of_environmentForDictionary: environment]; + env = [self of_environmentForDictionary: environment]; #ifdef HAVE_POSIX_SPAWNP posix_spawn_file_actions_t actions; posix_spawnattr_t attr; if (posix_spawn_file_actions_init(&actions) != 0) @@ -204,13 +203,20 @@ if (_pid == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #endif } @finally { + char **iter; + close(_readPipe[1]); close(_writePipe[0]); - [self freeMemory: argv]; + free(argv); + + for (iter = env; *iter != NULL; iter++) + free(*iter); + + free(env); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @@ -234,12 +240,11 @@ { OFString *const *objects = arguments.objects; size_t i, count = arguments.count; of_string_encoding_t encoding; - *argv = [self allocMemoryWithSize: sizeof(char *) - count: count + 2]; + *argv = of_malloc(count + 2, sizeof(char *)); encoding = [OFLocale encoding]; (*argv)[0] = (char *)[programName cStringWithEncoding: encoding]; @@ -250,48 +255,55 @@ (*argv)[i + 1] = NULL; } - (char **)of_environmentForDictionary: (OFDictionary *)environment { - OFEnumerator *keyEnumerator, *objectEnumerator; char **envp; - size_t i, count; + size_t count; of_string_encoding_t encoding; if (environment == nil) return NULL; encoding = [OFLocale encoding]; count = environment.count; - envp = [self allocMemoryWithSize: sizeof(char *) - count: count + 1]; - - keyEnumerator = [environment keyEnumerator]; - objectEnumerator = [environment objectEnumerator]; - - for (i = 0; i < count; i++) { - OFString *key; - OFString *object; - size_t keyLen, objectLen; - - key = [keyEnumerator nextObject]; - object = [objectEnumerator nextObject]; - - keyLen = [key cStringLengthWithEncoding: encoding]; - objectLen = [object cStringLengthWithEncoding: encoding]; - - envp[i] = [self allocMemoryWithSize: keyLen + objectLen + 2]; - - memcpy(envp[i], [key cStringWithEncoding: encoding], keyLen); - envp[i][keyLen] = '='; - memcpy(envp[i] + keyLen + 1, - [object cStringWithEncoding: encoding], objectLen); - envp[i][keyLen + objectLen + 1] = '\0'; - } - - envp[i] = NULL; + envp = of_calloc(count + 1, sizeof(char *)); + + @try { + OFEnumerator *keyEnumerator = [environment keyEnumerator]; + OFEnumerator *objectEnumerator = [environment objectEnumerator]; + + for (size_t i = 0; i < count; i++) { + OFString *key; + OFString *object; + size_t keyLen, objectLen; + + key = [keyEnumerator nextObject]; + object = [objectEnumerator nextObject]; + + keyLen = [key cStringLengthWithEncoding: encoding]; + objectLen = [object + cStringLengthWithEncoding: encoding]; + + envp[i] = of_malloc(keyLen + objectLen + 2, 1); + + memcpy(envp[i], + [key cStringWithEncoding: encoding], keyLen); + envp[i][keyLen] = '='; + memcpy(envp[i] + keyLen + 1, + [object cStringWithEncoding: encoding], objectLen); + envp[i][keyLen + objectLen + 1] = '\0'; + } + } @catch (id e) { + for (size_t i = 0; i < count; i++) + free(envp[i]); + + free(envp); + + @throw e; + } return envp; } - (bool)lowlevelIsAtEndOfStream Index: src/platform/posix/OFString+PathAdditions.m ================================================================== --- src/platform/posix/OFString+PathAdditions.m +++ src/platform/posix/OFString+PathAdditions.m @@ -152,12 +152,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } - ret = [fileName substringWithRange: - of_range(pos + 1, fileName.length - pos - 1)]; + ret = [fileName substringFromIndex: pos + 1]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -222,11 +221,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } - fileName = [fileName substringWithRange: of_range(0, pos)]; + fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: [components count] - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; @@ -332,15 +331,15 @@ - (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost { OFString *path = self; if (path.length > 1 && [path hasSuffix: @"/"]) - path = [path substringWithRange: of_range(0, path.length - 1)]; + path = [path substringToIndex: path.length - 1]; return path; } - (OFString *)of_pathComponentToURLPathComponent { return self; } @end Index: src/platform/windows/OFProcess.m ================================================================== --- src/platform/windows/OFProcess.m +++ src/platform/windows/OFProcess.m @@ -193,13 +193,11 @@ si.hStdOutput = _readPipe[1]; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; length = argumentsString.UTF16StringLength; - argumentsCopy = [self - allocMemoryWithSize: sizeof(of_char16_t) - count: length + 1]; + argumentsCopy = of_malloc(length + 1, sizeof(of_char16_t)); memcpy(argumentsCopy, argumentsString.UTF16String, (length + 1) * 2); @try { if (!CreateProcessW(program.UTF16String, argumentsCopy, NULL, NULL, TRUE, @@ -207,11 +205,11 @@ [self of_wideEnvironmentForDictionary: environment], NULL, &si, &pi)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @finally { - [self freeMemory: argumentsCopy]; + free(argumentsCopy); } } else { of_string_encoding_t encoding = [OFLocale encoding]; STARTUPINFO si; Index: src/platform/windows/OFString+PathAdditions.m ================================================================== --- src/platform/windows/OFString+PathAdditions.m +++ src/platform/windows/OFString+PathAdditions.m @@ -163,12 +163,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } - ret = [fileName substringWithRange: - of_range(pos + 1, fileName.length - pos - 1)]; + ret = [fileName substringFromIndex: pos + 1]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -233,11 +232,11 @@ if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } - fileName = [fileName substringWithRange: of_range(0, pos)]; + fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; @@ -356,13 +355,13 @@ { OFString *path = self; if (path.length > 1 && [path hasSuffix: @"/"] && ![path hasSuffix: @":/"]) - path = [path substringWithRange: of_range(0, path.length - 1)]; + path = [path substringToIndex: path.length - 1]; - path = [path substringWithRange: of_range(1, path.length - 1)]; + path = [path substringFromIndex: 1]; path = [path stringByReplacingOccurrencesOfString: @"/" withString: @"\\"]; if (URLEncodedHost != nil) { OFString *host = [URLEncodedHost stringByURLDecoding]; Index: src/scrypt.m ================================================================== --- src/scrypt.m +++ src/scrypt.m @@ -164,21 +164,21 @@ if (param.costFactor > SIZE_MAX - 1 || (param.costFactor + 1) > SIZE_MAX / 128) @throw [OFOutOfRangeException exception]; tmp = [[OFSecureData alloc] - initWithItemSize: param.blockSize - count: (param.costFactor + 1) * 128 + initWithCount: (param.costFactor + 1) * 128 + itemSize: param.blockSize allowsSwappableMemory: param.allowsSwappableMemory]; tmpItems = tmp.mutableItems; if (param.parallelization > SIZE_MAX / 128) @throw [OFOutOfRangeException exception]; buffer = [[OFSecureData alloc] - initWithItemSize: param.blockSize - count: param.parallelization * 128 + initWithCount: param.parallelization * 128 + itemSize: param.blockSize allowsSwappableMemory: param.allowsSwappableMemory]; bufferItems = buffer.mutableItems; HMAC = [[OFHMAC alloc] initWithHashClass: [OFSHA256Hash class] Index: src/socket.h ================================================================== --- src/socket.h +++ src/socket.h @@ -217,11 +217,11 @@ * @brief Returns the hash for the specified of_socket_address_t. * * @param address The address to hash * @return The hash for the specified of_socket_address_t */ -extern uint32_t of_socket_address_hash( +extern unsigned long of_socket_address_hash( const of_socket_address_t *_Nonnull address); /** * @brief Converts the specified of_socket_address_t to an IP string and port. * Index: src/socket.m ================================================================== --- src/socket.m +++ src/socket.m @@ -437,14 +437,12 @@ addrIn6->sin6_port = OF_BSWAP16_IF_LE(port); doubleColon = [IPv6 rangeOfString: @"::"].location; if (doubleColon != OF_NOT_FOUND) { - OFString *left = [IPv6 substringWithRange: - of_range(0, doubleColon)]; - OFString *right = [IPv6 substringWithRange: - of_range(doubleColon + 2, IPv6.length - doubleColon - 2)]; + OFString *left = [IPv6 substringToIndex: doubleColon]; + OFString *right = [IPv6 substringFromIndex: doubleColon + 2]; OFArray OF_GENERIC(OFString *) *leftComponents; OFArray OF_GENERIC(OFString *) *rightComponents; size_t i; if ([right hasPrefix: @":"] || [right containsString: @"::"]) @@ -606,11 +604,11 @@ } return true; } -uint32_t +unsigned long of_socket_address_hash(const of_socket_address_t *address) { uint32_t hash; OF_HASH_INIT(hash); Index: src/thread.h ================================================================== --- src/thread.h +++ src/thread.h @@ -39,11 +39,11 @@ struct Task *task; void (*function)(id); id object; struct SignalSemaphore semaphore; struct Task *joinTask; - uint8_t joinSigBit; + unsigned char joinSigBit; bool detached, done; } *of_thread_t; #endif typedef struct of_thread_attr_t { Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -36,10 +36,11 @@ OFXMLElementBuilderTests.m \ OFXMLNodeTests.m \ OFXMLParserTests.m \ PBKDF2Tests.m \ RuntimeTests.m \ + ${RUNTIME_ARC_TESTS_M} \ ScryptTests.m \ TestsAppDelegate.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ @@ -201,8 +202,9 @@ ${PROG_NOINST}.3dsx: ${PROG_NOINST} 3dsxtool $< $@ CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. -DSTDOUT +OBJCFLAGS_RuntimeARCTests.m = -fobjc-arc -fobjc-arc-exceptions LIBS := ${TESTS_LIBS} ${LIBS} LDFLAGS += ${MAP_LDFLAGS} LD = ${OBJC} Index: tests/OFDataTests.m ================================================================== --- tests/OFDataTests.m +++ tests/OFDataTests.m @@ -34,13 +34,12 @@ of_range_t range; TEST(@"+[dataWithItemSize:]", (mutable = [OFMutableData dataWithItemSize: 4096])) - OFObject *tmp = [[[OFObject alloc] init] autorelease]; - raw[0] = [tmp allocMemoryWithSize: 4096]; - raw[1] = [tmp allocMemoryWithSize: 4096]; + raw[0] = of_malloc(1, 4096); + raw[1] = of_malloc(1, 4096); memset(raw[0], 0xFF, 4096); memset(raw[1], 0x42, 4096); TEST(@"-[addItem:]", R([mutable addItem: raw[0]]) && R([mutable addItem: raw[1]])) @@ -53,12 +52,12 @@ TEST(@"-[count]", mutable.count == 2) TEST(@"-[isEqual:]", (immutable = [OFData dataWithItems: mutable.items - itemSize: mutable.itemSize - count: mutable.count]) && + count: mutable.count + itemSize: mutable.itemSize]) && [immutable isEqual: mutable] && R([mutable removeLastItem]) && ![mutable isEqual: immutable]) TEST(@"-[mutableCopy]", (mutable = [[immutable mutableCopy] autorelease]) && @@ -90,73 +89,73 @@ atIndex: 1 count: 2]) && mutable.count == 5 && memcmp(mutable.items, "abcde", 5) == 0) immutable = [OFData dataWithItems: "aaabaccdacaabb" - itemSize: 2 - count: 7]; + count: 7 + itemSize: 2]; TEST(@"-[rangeOfString:options:range:]", R(range = [immutable rangeOfData: [OFData dataWithItems: "aa" - itemSize: 2 - count: 1] + count: 1 + itemSize: 2] options: 0 range: of_range(0, 7)]) && range.location == 0 && range.length == 1 && R(range = [immutable rangeOfData: [OFData dataWithItems: "aa" - itemSize: 2 - count: 1] + count: 1 + itemSize: 2] options: OF_DATA_SEARCH_BACKWARDS range: of_range(0, 7)]) && range.location == 5 && range.length == 1 && R(range = [immutable rangeOfData: [OFData dataWithItems: "ac" - itemSize: 2 - count: 1] + count: 1 + itemSize: 2] options: 0 range: of_range(0, 7)]) && range.location == 2 && range.length == 1 && R(range = [immutable rangeOfData: [OFData dataWithItems: "aabb" - itemSize: 2 - count: 2] + count: 2 + itemSize: 2] options: 0 range: of_range(0, 7)]) && range.location == 5 && range.length == 2 && R(range = [immutable rangeOfData: [OFData dataWithItems: "aa" - itemSize: 2 - count: 1] + count: 1 + itemSize: 2] options: 0 range: of_range(1, 6)]) && range.location == 5 && range.length == 1 && R(range = [immutable rangeOfData: [OFData dataWithItems: "aa" - itemSize: 2 - count: 1] + count: 1 + itemSize: 2] options: OF_DATA_SEARCH_BACKWARDS range: of_range(0, 5)]) && range.location == 0 && range.length == 1) EXPECT_EXCEPTION( @"-[rangeOfString:options:range:] failing on different itemSize", OFInvalidArgumentException, [immutable rangeOfData: [OFData dataWithItems: "aaa" - itemSize: 3 - count: 1] + count: 1 + itemSize: 3] options: 0 range: of_range(0, 1)]) EXPECT_EXCEPTION( @"-[rangeOfData:options:range:] failing on out of range", OFOutOfRangeException, [immutable rangeOfData: [OFData dataWithItems: "" - itemSize: 2 - count: 0] + count: 0 + itemSize: 2] options: 0 range: of_range(8, 1)]) TEST(@"-[subdataWithRange:]", [[immutable subdataWithRange: of_range(2, 4)] isEqual: [OFData dataWithItems: "accdacaa" - itemSize: 2 - count: 4]] && + count: 4 + itemSize: 2]] && [[mutable subdataWithRange: of_range(2, 3)] isEqual: [OFData dataWithItems: "cde" count: 3]]) EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1", @@ -205,9 +204,12 @@ count: SIZE_MAX]) EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]", OFOutOfRangeException, [mutable removeItemsInRange: of_range(mutable.count, 1)]) + + free(raw[0]); + free(raw[1]); objc_autoreleasePoolPop(pool); } @end Index: tests/OFHTTPClientTests.m ================================================================== --- tests/OFHTTPClientTests.m +++ tests/OFHTTPClientTests.m @@ -99,11 +99,14 @@ } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response_ + exception: (id)exception { + OF_ENSURE(exception == nil); + response = [response_ retain]; [[OFRunLoop mainRunLoop] stop]; } Index: tests/OFObjectTests.m ================================================================== --- tests/OFObjectTests.m +++ tests/OFObjectTests.m @@ -85,53 +85,12 @@ @implementation TestsAppDelegate (OFObjectTests) - (void)objectTests { void *pool = objc_autoreleasePoolPush(); - OFObject *obj = [[[OFObject alloc] init] autorelease]; - void *p, *q, *r; OFObject *o; MyObj *m; - char *tmp; - - TEST(@"Allocating 4096 bytes", - (p = [obj allocMemoryWithSize: 4096]) != NULL) - - TEST(@"Freeing memory", R([obj freeMemory: p])) - - TEST(@"Allocating and freeing 4096 bytes 3 times", - (p = [obj allocMemoryWithSize: 4096]) != NULL && - (q = [obj allocMemoryWithSize: 4096]) != NULL && - (r = [obj allocMemoryWithSize: 4096]) != NULL && - R([obj freeMemory: p]) && R([obj freeMemory: q]) && - R([obj freeMemory: r])) - - tmp = [self allocMemoryWithSize: 1024]; - EXPECT_EXCEPTION(@"Detect freeing of memory not allocated by object", - OFMemoryNotPartOfObjectException, [obj freeMemory: tmp]) - - EXPECT_EXCEPTION(@"Detect out of memory on alloc", - OFOutOfMemoryException, tmp = [obj allocMemoryWithSize: TOO_BIG]) - - EXPECT_EXCEPTION(@"Detect out of memory on resize", - OFOutOfMemoryException, - { - p = [obj allocMemoryWithSize: 1]; - p = [obj resizeMemory: p - size: TOO_BIG]; - }) - [obj freeMemory: p]; - - TEST(@"Allocate when trying to resize NULL", - (p = [obj resizeMemory: NULL - size: 1024]) != NULL) - [obj freeMemory: p]; - - EXPECT_EXCEPTION(@"Detect resizing of memory not allocated by object", - OFMemoryNotPartOfObjectException, tmp = [obj resizeMemory: tmp - size: 2048]) - [self freeMemory: tmp]; TEST(@"+[description]", [[OFObject description] isEqual: @"OFObject"] && [[MyObj description] isEqual: @"MyObj"]) Index: tests/OFStreamTests.m ================================================================== --- tests/OFStreamTests.m +++ tests/OFStreamTests.m @@ -69,16 +69,18 @@ size_t pageSize = [OFSystemInfo pageSize]; StreamTester *t = [[[StreamTester alloc] init] autorelease]; OFString *str; char *cstr; - cstr = [t allocMemoryWithSize: pageSize - 2]; + cstr = of_malloc(pageSize - 2, 1); memset(cstr, 'X', pageSize - 3); cstr[pageSize - 3] = '\0'; TEST(@"-[readLine]", [[t readLine] isEqual: @"foo"] && [(str = [t readLine]) length] == pageSize - 3 && !strcmp(str.UTF8String, cstr)) + + free(cstr); objc_autoreleasePoolPop(pool); } @end ADDED tests/RuntimeARCTests.m Index: tests/RuntimeARCTests.m ================================================================== --- tests/RuntimeARCTests.m +++ tests/RuntimeARCTests.m @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * 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 "TestsAppDelegate.h" + +static OFString *module = @"Runtime (ARC)"; + +@interface RuntimeARCTest: OFObject +@end + +@implementation RuntimeARCTest +- (instancetype)init +{ + self = [super init]; + + @throw [OFException exception]; + + return self; +} +@end + +@implementation TestsAppDelegate (RuntimeARCTests) +- (void)runtimeARCTests +{ + id object; + __weak id weak; + + EXPECT_EXCEPTION(@"Exceptions in init", OFException, + object = [[RuntimeARCTest alloc] init]) + + object = [[OFObject alloc] init]; + weak = object; + TEST(@"weakly referencing an object", weak == object) + + object = nil; + TEST(@"weak references becoming nil", weak == nil) +} +@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -175,10 +175,14 @@ @end @interface TestsAppDelegate (RuntimeTests) - (void)runtimeTests; @end + +@interface TestsAppDelegate (RuntimeARCTests) +- (void)runtimeARCTests; +@end @interface TestsAppDelegate (OFRIPEMD160HashTests) - (void)RIPEMD160HashTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -312,10 +312,13 @@ [[OFFileManager defaultManager] changeCurrentDirectoryPath: @"/apps/objfw-tests"]; #endif [self runtimeTests]; +#ifdef COMPILER_SUPPORTS_ARC + [self runtimeARCTests]; +#endif [self objectTests]; [self methodSignatureTests]; [self invocationTests]; [self forwardingTests]; #ifdef OF_HAVE_BLOCKS Index: utils/ofhttp/OFHTTP.m ================================================================== --- utils/ofhttp/OFHTTP.m +++ utils/ofhttp/OFHTTP.m @@ -63,11 +63,11 @@ OFArray OF_GENERIC(OFString *) *_URLs; size_t _URLIndex; int _errorCode; OFString *_outputPath, *_currentFileName; bool _continue, _force, _detectFileName, _detectFileNameRequest; - bool _detectedFileName, _quiet, _verbose, _insecure; + bool _detectedFileName, _quiet, _verbose, _insecure, _ignoreStatus; OFStream *_body; of_http_request_method_t _method; OFMutableDictionary *_clientHeaders; OFHTTPClient *_HTTPClient; char *_buffer; @@ -116,11 +116,13 @@ @"-q --quiet " @" Quiet mode (no output, except errors)\n " @"-v --verbose " @" Verbose mode (print headers)\n " @" --insecure " - @" Ignore TLS errors and allow insecure redirects")]; + @" Ignore TLS errors and allow insecure redirects\n " + @" --ignore-status " + @" Ignore HTTP status code")]; } [OFApplication terminateWithStatus: status]; } @@ -300,11 +302,11 @@ forKey: @"User-Agent"]; _HTTPClient = [[OFHTTPClient alloc] init]; _HTTPClient.delegate = self; - _buffer = [self allocMemoryWithSize: [OFSystemInfo pageSize]]; + _buffer = of_malloc(1, [OFSystemInfo pageSize]); } @catch (id e) { [self release]; @throw e; } @@ -321,16 +323,15 @@ @"%[prog]: Headers must to be in format name:value!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } - name = [header substringWithRange: of_range(0, pos)]; - name = name.stringByDeletingEnclosingWhitespaces; + name = [header substringToIndex: pos] + .stringByDeletingEnclosingWhitespaces; - value = [header substringWithRange: - of_range(pos + 1, header.length - pos - 1)]; - value = value.stringByDeletingEnclosingWhitespaces; + value = [header substringFromIndex: pos + 1] + .stringByDeletingEnclosingWhitespaces; [_clientHeaders setObject: value forKey: name]; } @@ -394,13 +395,13 @@ unsigned long long port; if (pos == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; - host = [proxy substringWithRange: of_range(0, pos)]; - port = [proxy substringWithRange: of_range(pos + 1, - proxy.length - pos - 1)].unsignedLongLongValue; + host = [proxy substringToIndex: pos]; + port = [proxy substringFromIndex: pos + 1] + .unsignedLongLongValue; if (port > UINT16_MAX) @throw [OFOutOfRangeException exception]; [OFTCPSocket setSOCKS5Host: host]; @@ -427,10 +428,11 @@ { 'O', @"detect-filename", 0, &_detectFileName, NULL }, { 'P', @"socks5-proxy", 1, NULL, NULL }, { 'q', @"quiet", 0, &_quiet, NULL }, { 'v', @"verbose", 0, &_verbose, NULL }, { '\0', @"insecure", 0, &_insecure, NULL }, + { '\0', @"ignore-status", 0, &_ignoreStatus, NULL }, { '\0', nil, 0, NULL, NULL } }; OFOptionsParser *optionsParser; of_unichar_t option; @@ -604,11 +606,11 @@ } } - (bool)client: (OFHTTPClient *)client shouldFollowRedirect: (OFURL *)URL - statusCode: (int)statusCode + statusCode: (short)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { if (_verbose) { void *pool = objc_autoreleasePoolPush(); @@ -632,99 +634,10 @@ _length = 0; return true; } -- (void)client: (OFHTTPClient *)client - didFailWithException: (id)e - request: (OFHTTPRequest *)request -{ - if ([e isKindOfClass: [OFResolveHostFailedException class]]) { - if (!_quiet) - [of_stdout writeString: @"\n"]; - - [of_stderr writeLine: - OF_LOCALIZED(@"download_resolve_host_failed", - @"%[prog]: Failed to download <%[url]>!\n" - @" Failed to resolve host: %[exception]", - @"prog", [OFApplication programName], - @"url", request.URL.string, - @"exception", e)]; - } else if ([e isKindOfClass: [OFConnectionFailedException class]]) { - if (!_quiet) - [of_stdout writeString: @"\n"]; - - [of_stderr writeLine: - OF_LOCALIZED(@"download_failed_connection_failed", - @"%[prog]: Failed to download <%[url]>!\n" - @" Connection failed: %[exception]", - @"prog", [OFApplication programName], - @"url", request.URL.string, - @"exception", e)]; - } else if ([e isKindOfClass: [OFInvalidServerReplyException class]]) { - if (!_quiet) - [of_stdout writeString: @"\n"]; - - [of_stderr writeLine: - OF_LOCALIZED(@"download_failed_invalid_server_reply", - @"%[prog]: Failed to download <%[url]>!\n" - @" Invalid server reply!", - @"prog", [OFApplication programName], - @"url", request.URL.string)]; - } else if ([e isKindOfClass: [OFUnsupportedProtocolException class]]) { - if (!_quiet) - [of_stdout writeString: @"\n"]; - - [of_stderr writeLine: OF_LOCALIZED(@"no_ssl_library", - @"%[prog]: No TLS library loaded!\n" - @" In order to download via https, you need to preload an " - @"TLS library for ObjFW\n" - @" such as ObjOpenSSL!", - @"prog", [OFApplication programName])]; - } else if ([e isKindOfClass: [OFReadOrWriteFailedException class]]) { - OFString *error = OF_LOCALIZED( - @"download_failed_read_or_write_failed_any", - @"Read or write failed"); - - if (!_quiet) - [of_stdout writeString: @"\n"]; - - if ([e isKindOfClass: [OFReadFailedException class]]) - error = OF_LOCALIZED( - @"download_failed_read_or_write_failed_read", - @"Read failed"); - else if ([e isKindOfClass: [OFWriteFailedException class]]) - error = OF_LOCALIZED( - @"download_failed_read_or_write_failed_write", - @"Write failed"); - - [of_stderr writeLine: - OF_LOCALIZED(@"download_failed_read_or_write_failed", - @"%[prog]: Failed to download <%[url]>!\n" - @" %[error]: %[exception]", - @"prog", [OFApplication programName], - @"url", request.URL.string, - @"error", error, - @"exception", e)]; - } else if ([e isKindOfClass: [OFHTTPRequestFailedException class]]) { - short statusCode = [[e response] statusCode]; - OFString *codeString = [OFString stringWithFormat: @"%d %@", - statusCode, of_http_status_code_to_string(statusCode)]; - [of_stderr writeLine: OF_LOCALIZED(@"download_failed", - @"%[prog]: Failed to download <%[url]>!\n" - @" HTTP status code: %[code]", - @"prog", [OFApplication programName], - @"url", request.URL.string, - @"code", codeString)]; - } else - @throw e; - - _errorCode = 1; - [self performSelector: @selector(downloadNextURL) - afterDelay: 0]; -} - - (bool)stream: (OFStream *)response didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { @@ -784,11 +697,11 @@ return true; } - (void)client: (OFHTTPClient *)client didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers - statusCode: (int)statusCode + statusCode: (short)statusCode request: (OFHTTPRequest *)request { if (statusCode != 206) _resumedFrom = 0; @@ -795,11 +708,11 @@ if (!_quiet) { OFString *lengthString = [headers objectForKey: @"Content-Length"]; OFString *type = [headers objectForKey: @"Content-Type"]; - [of_stdout writeFormat: @" ➜ %d\n", statusCode]; + [of_stdout writeFormat: @" ➜ %hd\n", statusCode]; if (type == nil) type = OF_LOCALIZED(@"type_unknown", @"unknown"); if (lengthString != nil) { @@ -882,11 +795,119 @@ } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response + exception: (id)exception { + if (exception != nil) { + if ([exception isKindOfClass: + [OFResolveHostFailedException class]]) { + if (!_quiet) + [of_stdout writeString: @"\n"]; + + [of_stderr writeLine: + OF_LOCALIZED(@"download_resolve_host_failed", + @"%[prog]: Failed to download <%[url]>!\n" + @" Failed to resolve host: %[exception]", + @"prog", [OFApplication programName], + @"url", request.URL.string, + @"exception", exception)]; + } else if ([exception isKindOfClass: + [OFConnectionFailedException class]]) { + if (!_quiet) + [of_stdout writeString: @"\n"]; + + [of_stderr writeLine: + OF_LOCALIZED(@"download_failed_connection_failed", + @"%[prog]: Failed to download <%[url]>!\n" + @" Connection failed: %[exception]", + @"prog", [OFApplication programName], + @"url", request.URL.string, + @"exception", exception)]; + } else if ([exception isKindOfClass: + [OFInvalidServerReplyException class]]) { + if (!_quiet) + [of_stdout writeString: @"\n"]; + + [of_stderr writeLine: OF_LOCALIZED( + @"download_failed_invalid_server_reply", + @"%[prog]: Failed to download <%[url]>!\n" + @" Invalid server reply!", + @"prog", [OFApplication programName], + @"url", request.URL.string)]; + } else if ([exception isKindOfClass: + [OFUnsupportedProtocolException class]]) { + if (!_quiet) + [of_stdout writeString: @"\n"]; + + [of_stderr writeLine: OF_LOCALIZED(@"no_ssl_library", + @"%[prog]: No TLS library loaded!\n" + @" In order to download via https, you need to " + @"preload an TLS library for ObjFW\n" + @" such as ObjOpenSSL!", + @"prog", [OFApplication programName])]; + } else if ([exception isKindOfClass: + [OFReadOrWriteFailedException class]]) { + OFString *error = OF_LOCALIZED( + @"download_failed_read_or_write_failed_any", + @"Read or write failed"); + + if (!_quiet) + [of_stdout writeString: @"\n"]; + + if ([exception isKindOfClass: + [OFReadFailedException class]]) + error = OF_LOCALIZED( + @"download_failed_read_or_write_failed_" + @"read", + @"Read failed"); + else if ([exception isKindOfClass: + [OFWriteFailedException class]]) + error = OF_LOCALIZED( + @"download_failed_read_or_write_failed_" + @"write", + @"Write failed"); + + [of_stderr writeLine: OF_LOCALIZED( + @"download_failed_read_or_write_failed", + @"%[prog]: Failed to download <%[url]>!\n" + @" %[error]: %[exception]", + @"prog", [OFApplication programName], + @"url", request.URL.string, + @"error", error, + @"exception", exception)]; + } else if ([exception isKindOfClass: + [OFHTTPRequestFailedException class]]) { + short statusCode; + OFString *codeString; + + if (_ignoreStatus) { + exception = nil; + goto after_exception_handling; + } + + statusCode = response.statusCode; + codeString = [OFString stringWithFormat: @"%hd %@", + statusCode, + of_http_status_code_to_string(statusCode)]; + [of_stderr writeLine: OF_LOCALIZED(@"download_failed", + @"%[prog]: Failed to download <%[url]>!\n" + @" HTTP status code: %[code]", + @"prog", [OFApplication programName], + @"url", request.URL.string, + @"code", codeString)]; + } else + @throw exception; + + _errorCode = 1; + [self performSelector: @selector(downloadNextURL) + afterDelay: 0]; + return; + } + +after_exception_handling: if (_method == OF_HTTP_REQUEST_METHOD_HEAD) goto next; if (_detectFileNameRequest) { _currentFileName = [fileNameFromContentDisposition( Index: utils/ofhttp/lang/de.json ================================================================== --- utils/ofhttp/lang/de.json +++ utils/ofhttp/lang/de.json @@ -15,11 +15,12 @@ " -P --proxy SOCKS5-Proxy angeben\n", " -q --quiet Ruhiger Modus (keine Ausgabe außer Fehler)", "\n", " -v --verbose Ausführlicher Modus (gibt Header aus)\n", " --insecure TLS-Fehler ignorieren und unsichere\n", - " Weiterleitungen erlauben" + " Weiterleitungen erlauben\n", + " --ignore-status HTTP Status-Code ignorieren" ], "invalid_input_header": "%[prog]: Header müssen im Format Name:Wert sein!", "invalid_input_method": "%[prog]: Ungültige Request-Methode %[method]!", "invalid_input_proxy": "%[prog]: Proxy muss im Format Host:Port sein!", "long_argument_missing": "%[prog]: Argument für Option --%[opt] fehlt",