Index: .fossil-settings/clean-glob ================================================================== --- .fossil-settings/clean-glob +++ .fossil-settings/clean-glob @@ -26,10 +26,11 @@ generators/gen_tables src/Info.plist src/bridge/Info.plist src/inline.h src/objfw-defs.h +src/runtime/Info.plist src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/DerivedData tests/EBOOT.PBP tests/Info.plist Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -28,10 +28,11 @@ generators/gen_tables src/Info.plist src/bridge/Info.plist src/inline.h src/objfw-defs.h +src/runtime/Info.plist src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/DerivedData tests/EBOOT.PBP tests/Info.plist ADDED .github/FUNDING.yml Index: .github/FUNDING.yml ================================================================== --- .github/FUNDING.yml +++ .github/FUNDING.yml @@ -0,0 +1,1 @@ +github: Midar ADDED .github/ISSUE_TEMPLATE/config.yml Index: .github/ISSUE_TEMPLATE/config.yml ================================================================== --- .github/ISSUE_TEMPLATE/config.yml +++ .github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,21 @@ +blank_issues_enabled: true +contact_links: + - name: New ObjFW ticket + url: https://objfw.nil.im/tktnew + about: + Please use this to create a new ticket. You can also report issues on + GitHub, but this is preferred. + - name: Existing ObjFW tickets + url: https://objfw.nil.im/reportlist + about: Please use this to look for existing tickets. + - name: ObjFW Forum + url: https://objfw.nil.im/forum + about: Please use this if you have questions or want support. + - name: ObjFW Matrix Room + url: https://matrix.to/#/%23objfw:nil.im + about: Please use this for interactive questions and support. + - name: ObjFW IRC Channel + url: https://webchat.freenode.net/?channels=objfw + about: + Please use this for interactive questions and support - it is bridged to + the Matrix room above. Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -28,10 +28,11 @@ generators/gen_tables src/Info.plist src/bridge/Info.plist src/inline.h src/objfw-defs.h +src/runtime/Info.plist src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/DerivedData tests/EBOOT.PBP tests/Info.plist Index: .travis.yml ================================================================== --- .travis.yml +++ .travis.yml @@ -239,10 +239,12 @@ - os: linux dist: bionic env: - 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"; @@ -266,28 +268,16 @@ 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" - -o "$config" = "wii" ]; then - deb=devkitpro-pacman.amd64.deb; - wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/$deb; - sudo apt install gdebi; - sudo gdebi -n $deb; - fi - - - if [ "$config" = "nintendo_3ds" ]; then - sudo dkp-pacman --noconfirm -Syu 3ds-dev; - fi - - - if [ "$config" = "nintendo_ds" ]; then - sudo dkp-pacman --noconfirm -Syu nds-dev; + - if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" ]; then + docker pull devkitpro/devkitarm; fi - if [ "$config" = "wii" ]; then - sudo dkp-pacman --noconfirm -Syu wii-dev; + docker pull devkitpro/devkitppc; fi - if [ "$config" = "amigaos" ]; then wget -q https://franke.ms/download/amiga-gcc.tgz; tar -C / -xzf amiga-gcc.tgz; @@ -297,26 +287,12 @@ - build() { if ! git clean -fxd >/tmp/clean_log 2>&1; then cat /tmp/clean_log; exit 1; fi; - echo ">> Configuring with $@"; - ./autogen.sh; - if ! ./configure ac_cv_path_TPUT= "$@"; then - cat config.log; - exit 1; - fi; - echo ">> Building (configured with $@)"; - if ! make -j4 >/tmp/make_log 2>&1; then - cat /tmp/make_log; - exit 1; - fi; - echo ">> Installing (configured with $@)"; - if ! sudo PATH="$PATH" make install >/tmp/install_log 2>&1; then - cat /tmp/install_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" $@; @@ -423,24 +399,28 @@ build --host=m68k-amigaos --disable-amiga-lib; build --host=m68k-amigaos --enable-static; fi - if [ "$config" = "nintendo_3ds" ]; then - export DEVKITPRO="/opt/devkitpro"; - export PATH="$DEVKITPRO/devkitARM/bin:$PATH"; - - build --host=arm-none-eabi --with-3ds; + ./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 - export DEVKITPRO="/opt/devkitpro"; - export PATH="$DEVKITPRO/devkitARM/bin:$PATH"; - - build --host=arm-none-eabi --with-nds; + ./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 - export DEVKITPRO="/opt/devkitpro"; - export PATH="$DEVKITPRO/devkitPPC/bin:$PATH"; - - build ac_cv_prog_wiiload= --host=powerpc-eabi --with-wii; + ./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 ADDED .travis/build.sh Index: .travis/build.sh ================================================================== --- .travis/build.sh +++ .travis/build.sh @@ -0,0 +1,20 @@ +#!/bin/sh +cd $(dirname $0)/.. + +echo ">> Configuring with $@" +if ! ./configure ac_cv_path_TPUT= "$@"; then + cat config.log + exit 1 +fi + +echo ">> Building (configured with $@)" +if ! make -j4 >/tmp/make_log 2>&1; then + cat /tmp/make_log + exit 1 +fi + +echo ">> Installing (configured with $@)" +if ! sudo PATH="$PATH" make install >/tmp/install_log 2>&1; then + cat /tmp/install_log + exit 1 +fi Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -10,24 +10,24 @@ config.status \ extra.mk include buildsys.mk -.PHONY: docs tarball +.PHONY: docs release utils tests: src docs: rm -fr docs doxygen >/dev/null -tarball: docs +release: docs echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz fossil tarball --name objfw-${PACKAGE_VERSION} current - \ - --exclude '.fossil-settings/*,.gitignore,.travis.yml' | \ + --exclude '.cirrus*,.fossil*,.git*,.travis*' | \ ofarc -ttgz -xq - cp configure config.h.in objfw-${PACKAGE_VERSION}/ ofarc -cq objfw-${PACKAGE_VERSION}.tar \ $$(find objfw-${PACKAGE_VERSION} | sort) rm -fr objfw-${PACKAGE_VERSION} Index: PLATFORMS.md ================================================================== --- PLATFORMS.md +++ PLATFORMS.md @@ -33,11 +33,11 @@ DOS --- - * OS Versions: Windows XP DOS Emulation, DOSBox + * OS Versions: Windows XP DOS Emulation, DOSBox, MS-DOS 6.0, FreeDOS 1.2 * Architectures: x86 * Compilers: DJGPP GCC 4.7.3 (djdev204) * Runtimes: ObjFW @@ -87,13 +87,13 @@ macOS ----- - * OS Versions: 10.5, 10.7-10.14, Darling + * OS Versions: 10.5, 10.7-10.15, Darling * Architectures: PowerPC, PowerPC64, x86, x86_64 - * Compilers: Clang 3.1-10.0, GCC 4.2.1 + * Compilers: Clang 3.1-10.0, Apple GCC 4.0.1 & 4.2.1 * Runtimes: Apple, ObjFW MorphOS ------- @@ -107,13 +107,13 @@ NetBSD ------ * OS Versions: 5.1-9.0 - * Architectures: ARM, ARM (big endian, BE8 mode), MIPS (O32), SPARC, SPARC64, - x86, x86_64 - * Compilers: Clang 3.0-3.2, GCC 4.1.3 & 4.5.3 + * Architectures: ARM, ARM (big endian, BE8 mode), MIPS (O32), PowerPC, SPARC, + SPARC64, x86, x86_64 + * Compilers: Clang 3.0-3.2, GCC 4.1.3 & 4.5.3 & 7.4.0 * Runtimes: ObjFW Nintendo 3DS ------------ Index: README.md ================================================================== --- README.md +++ README.md @@ -119,16 +119,23 @@ It's also possible to open the same local repository multiple times, so that you have multiple working directories all backed by the same local repository. + In order to verify the signature of the currently checked out checkin, you + can use: + + $ fossil artifact current | gpg --verify +

Git

To clone the Git repository, use the following: $ git clone https://github.com/ObjFW/ObjFW + Git commits are not signed, so if you want to check the signature of an + individual commit, branch head or tag, please use Fossil.

Installation

To install ObjFW, just run the following commands: @@ -186,11 +193,11 @@ Unfortunately, there is no workaround for this other than to upgrade/downgrade Xcode or to build upstream Clang yourself. In particular, Xcode 11 Beta 1 to Beta 3 are known to be affected. While Xcode 11 Beta 4 to Xcode 11.3 work, the bug was unfortunately reintroduced in - Xcode 11.4.1 and a fix is not expected before Xcode 11.6. + Xcode 11.4.1 and was only fixed in Xcode 12 Beta 1. You can get older versions of Xcode [here](https://developer.apple.com/download) by clicking on "More" in the top-right corner. @@ -348,12 +355,13 @@ If you have any questions about ObjFW or would like to talk to other ObjFW users, the following venues are available: * The [forum](https://objfw.nil.im/forum) * A [Matrix](https://matrix.to/#/%23objfw:nil.im) room - * An [IRC channel](irc://chat.freenode.net/#objfw) on Freenode (`#objfw`), - bridged to the Matrix room above + * An [IRC channel](irc://chat.freenode.net/#objfw) on Freenode (`#objfw`, + [web chat](https://webchat.freenode.net/?channels=objfw)), bridged to the + Matrix room above Please don't hesitate to join any or all of those!

Commercial use

Index: buildsys.mk.in ================================================================== --- buildsys.mk.in +++ buildsys.mk.in @@ -189,11 +189,11 @@ fi ${FRAMEWORK} ${FRAMEWORK_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LINK_STATUS} out="$@"; \ - if rm -fr $$out && ${MKDIR_P} $$out && ${MAKE} -s COPY_HEADERS_IF_SUBDIR=${includesubdir} COPY_HEADERS_DESTINATION=$$PWD/$@/Headers copy-headers-into-framework && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Info.plist; fi && if test -f module.modulemap; then ${MKDIR_P} $$out/Modules && ${INSTALL} -m 644 module.modulemap $$out/Modules/module.modulemap; fi && ${LD} -o $$out/$${out%.framework} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${FRAMEWORK_LDFLAGS} ${FRAMEWORK_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${FRAMEWORK_LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} --timestamp=none $$out; then \ + if rm -fr $$out && ${MKDIR_P} $$out && ${MAKE} -s COPY_HEADERS_IF_SUBDIR=${includesubdir} COPY_HEADERS_DESTINATION=$$PWD/$@/Headers copy-headers-into-framework && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Info.plist; fi && if test -f module.modulemap; then ${MKDIR_P} $$out/Modules && ${INSTALL} -m 644 module.modulemap $$out/Modules/module.modulemap; fi && ${LD} -o $$out/$${out%.framework} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${FRAMEWORK_LDFLAGS} ${FRAMEWORK_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${FRAMEWORK_LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} $$out; then \ ${LINK_OK}; \ else \ rm -fr $$out; false; \ ${LINK_FAILED}; \ fi Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -429,10 +429,11 @@ AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins]) AS_IF([test x"$enable_files" != x"no" -a x"$PLUGIN_SUFFIX" != x""], [ AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}') AC_SUBST(TESTPLUGIN, "plugin") AC_DEFINE(OF_HAVE_PLUGINS, 1, [Whether we have plugin support]) + AC_CONFIG_FILES(tests/plugin/Info.plist) AS_IF([test x"$build_framework" = x"yes"], [ TESTPLUGIN_LIBS="-F../../src -F../../src/runtime" TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS -framework ObjFW" TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS \${RUNTIME_FRAMEWORK_LIBS}" @@ -543,10 +544,11 @@ AC_MSG_RESULT(no) old_compiler="yes" ]) AC_SUBST(RUNTIME, "runtime") + AC_CONFIG_FILES(src/runtime/Info.plist) AS_IF([test x"$enable_shared" != x"no"], [ AC_SUBST(OBJFWRT_SHARED_LIB, "${LIB_PREFIX}objfwrt${LIB_SUFFIX}") ]) @@ -651,19 +653,22 @@ AC_SUBST(RUNTIME_LIBS, "-lobjc") AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-lobjc") ], [ AC_MSG_ERROR([libobjc not found!]) ]) + + 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") + ]) ;; esac AC_CHECK_FUNCS(_Unwind_Backtrace) -AC_CHECK_FUNC(objc_autoreleasePoolPush, [], [ - AC_SUBST(AUTORELEASE_M, "autorelease.m") -]) - case "$host_os" in darwin*) AC_SUBST(LDFLAGS_REEXPORT, ["-Wl,-reexport-lobjfw"]) AS_IF([test x"$objc_runtime" = x"Apple runtime"], [ AC_SUBST(REEXPORT_RUNTIME, ["-Wl,-reexport-lobjc"]) @@ -838,11 +843,11 @@ AC_MSG_CHECKING(for VFP2 or above) AC_TRY_COMPILE([], [ #if !defined(__arm64__) && !defined(__aarch64__) && \ !defined(__ARM64_ARCH_8__) __asm__ __volatile__ ( - "fstmfdd sp!, {d0-d7}" + "vstmdb sp!, {d0-d7}" ); #endif ], [ AC_DEFINE(HAVE_VFP2, 1, [Whether we have VFP2 or above]) AC_MSG_RESULT(yes) @@ -924,17 +929,11 @@ AC_SUBST(ENCODINGS_ENCODINGS_AMIGALIB_A, "encodings/encodings.amigalib.a") ]) ]) -AC_CHECK_FUNC(arc4random, [ - AC_DEFINE(OF_HAVE_ARC4RANDOM, 1, [Whether we have arc4random()]) -], [ - AC_CHECK_FUNC(random, [ - AC_DEFINE(OF_HAVE_RANDOM, 1, [Whether we have random()]) - ]) -]) +AC_CHECK_FUNCS(arc4random arc4random_buf getrandom random, break) AS_IF([test x"$host_os" != x"morphos"], [ AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") ]) AC_CHECK_HEADERS_ONCE(dlfcn.h) @@ -1603,10 +1602,11 @@ ]) AS_IF([test x"$objc_runtime" = x"Apple runtime"], [ AC_CHECK_HEADER(Foundation/NSObject.h, [ AC_SUBST(BRIDGE, "bridge") + AC_CONFIG_FILES(src/bridge/Info.plist) AS_IF([test x"$enable_shared" != x"no"], [ AC_SUBST(OBJFWBRIDGE_SHARED_LIB, "${LIB_PREFIX}objfwbridge${LIB_SUFFIX}") ]) @@ -1806,11 +1806,11 @@ old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Wdocumentation" AC_MSG_CHECKING(whether -Wdocumentation works correctly) AC_TRY_COMPILE([ - /*! + /** * @class Test conftest.m conftest.m */ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) @@ -1938,13 +1938,11 @@ AC_CONFIG_FILES([ buildsys.mk extra.mk src/Info.plist - src/bridge/Info.plist tests/Info.plist - tests/plugin/Info.plist utils/objfw-config ]) AC_CONFIG_HEADERS([config.h src/objfw-defs.h]) AC_OUTPUT Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -16,11 +16,10 @@ OBJFWBRIDGE_SHARED_LIB = @OBJFWBRIDGE_SHARED_LIB@ OBJFWBRIDGE_STATIC_LIB = @OBJFWBRIDGE_STATIC_LIB@ OBJFWBRIDGE_FRAMEWORK = @OBJFWBRIDGE_FRAMEWORK@ -AUTORELEASE_M = @AUTORELEASE_M@ BIN_PREFIX = @BIN_PREFIX@ BRIDGE = @BRIDGE@ CVINCLUDE_INLINE_H = @CVINCLUDE_INLINE_H@ ENCODINGS = @ENCODINGS@ ENCODINGS_A = @ENCODINGS_A@ @@ -41,11 +40,10 @@ FORWARDING_AMIGALIB_A = @FORWARDING_AMIGALIB_A@ FORWARDING_FORWARDING_A = @FORWARDING_FORWARDING_A@ FORWARDING_FORWARDING_AMIGALIB_A = @FORWARDING_FORWARDING_AMIGALIB_A@ FORWARDING_FORWARDING_LIB_A = @FORWARDING_FORWARDING_LIB_A@ FORWARDING_LIB_A = @FORWARDING_LIB_A@ -INSTANCE_M = @INSTANCE_M@ INVOCATION_A = @INVOCATION_A@ INVOCATION_AMIGALIB_A = @INVOCATION_AMIGALIB_A@ INVOCATION_INVOCATION_A = @INVOCATION_INVOCATION_A@ INVOCATION_INVOCATION_AMIGALIB_A = @INVOCATION_INVOCATION_AMIGALIB_A@ INVOCATION_INVOCATION_LIB_A = @INVOCATION_INVOCATION_LIB_A@ @@ -77,11 +75,13 @@ 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_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@ SFDC_INLINE_H = @SFDC_INLINE_H@ SFDC_TARGET = @SFDC_TARGET@ SFD_FILE = @SFD_FILE@ Index: generators/TableGenerator.m ================================================================== --- generators/TableGenerator.m +++ generators/TableGenerator.m @@ -119,22 +119,22 @@ if (components.count != 15) { of_log(@"Invalid line: %@\n", line); [OFApplication terminateWithStatus: 1]; } - codePoint = (of_unichar_t) - [[components objectAtIndex: 0] hexadecimalValue]; + codePoint = (of_unichar_t)[[components objectAtIndex: 0] + unsignedLongLongValueWithBase: 16]; if (codePoint > 0x10FFFF) @throw [OFOutOfRangeException exception]; - _uppercaseTable[codePoint] = (of_unichar_t) - [[components objectAtIndex: 12] hexadecimalValue]; - _lowercaseTable[codePoint] = (of_unichar_t) - [[components objectAtIndex: 13] hexadecimalValue]; - _titlecaseTable[codePoint] = (of_unichar_t) - [[components objectAtIndex: 14] hexadecimalValue]; + _uppercaseTable[codePoint] = (of_unichar_t)[[components + objectAtIndex: 12] unsignedLongLongValueWithBase: 16]; + _lowercaseTable[codePoint] = (of_unichar_t)[[components + objectAtIndex: 13] unsignedLongLongValueWithBase: 16]; + _titlecaseTable[codePoint] = (of_unichar_t)[[components + objectAtIndex: 14] unsignedLongLongValueWithBase: 16]; if ([[components objectAtIndex: 5] length] > 0) { OFArray *decomposed = [[components objectAtIndex: 5] componentsSeparatedByString: @" "]; bool compat = false; @@ -147,12 +147,12 @@ } string = [OFMutableString string]; for (OFString *character in decomposed) { - of_unichar_t unichar = - (of_unichar_t)character.hexadecimalValue; + of_unichar_t unichar = (of_unichar_t)[character + unsignedLongLongValueWithBase: 16]; [string appendCharacters: &unichar length: 1]; } @@ -202,18 +202,18 @@ if (![[components objectAtIndex: 1] isEqual: @"S"] && ![[components objectAtIndex: 1] isEqual: @"C"]) continue; - codePoint = (of_unichar_t) - [[components objectAtIndex: 0] hexadecimalValue]; + codePoint = (of_unichar_t)[[components objectAtIndex: 0] + unsignedLongLongValueWithBase: 16]; if (codePoint > 0x10FFFF) @throw [OFOutOfRangeException exception]; - _casefoldingTable[codePoint] = (of_unichar_t) - [[components objectAtIndex: 2] hexadecimalValue]; + _casefoldingTable[codePoint] = (of_unichar_t)[[components + objectAtIndex: 2] unsignedLongLongValueWithBase: 16]; objc_autoreleasePoolPop(pool2); } [of_stdout writeLine: @" done"]; @@ -265,10 +265,12 @@ [table[i] release]; table[i] = [replacement copy]; done = false; } + + objc_autoreleasePoolPop(pool); } } while (!done); } - (void)writeFiles Index: src/Info.plist.in ================================================================== --- src/Info.plist.in +++ src/Info.plist.in @@ -5,11 +5,11 @@ CFBundleExecutable ObjFW CFBundleName ObjFW CFBundleIdentifier - zone.heap.objfw + im.nil.objfw CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType FMWK CFBundleVersion Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -36,13 +36,13 @@ OFCharacterSet.m \ OFColor.m \ OFConstantString.m \ OFCountedSet.m \ OFData.m \ - OFData+ASN1DERValue.m \ + OFData+ASN1DERParsing.m \ OFData+CryptoHashing.m \ - OFData+MessagePackValue.m \ + OFData+MessagePackParsing.m \ OFDate.m \ OFDictionary.m \ OFEnumerator.m \ OFFileManager.m \ OFGZIPStream.m \ @@ -93,12 +93,12 @@ OFSortedList.m \ OFStdIOStream.m \ OFStream.m \ OFString.m \ OFString+CryptoHashing.m \ - OFString+JSONValue.m \ - OFString+PropertyListValue.m \ + OFString+JSONParsing.m \ + OFString+PropertyListParsing.m \ OFString+Serialization.m \ OFString+URLEncoding.m \ OFString+XMLEscaping.m \ OFString+XMLUnescaping.m \ OFSystemInfo.m \ @@ -221,11 +221,13 @@ OFRangeCharacterSet.m \ OFRangeValue.m \ OFRectangleValue.m \ OFSubarray.m \ OFUTF8String.m \ - ${LIBBASES_M} + ${LIBBASES_M} \ + ${RUNTIME_AUTORELEASE_M} \ + ${RUNTIME_INSTANCE_M} SRCS_FILES += OFFileURLHandler.m \ OFINIFileSettings.m SRCS_SOCKETS += OFDNSResolverSettings.m \ OFHTTPURLHandler.m \ OFHostAddressResolver.m \ Index: src/OFASN1BitString.h ================================================================== --- src/OFASN1BitString.h +++ src/OFASN1BitString.h @@ -21,31 +21,31 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; -/*! +/** * @brief An ASN.1 BitString. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1BitString: OFObject { OFData *_bitStringValue; size_t _bitStringLength; } -/*! +/** * @brief The BitString value. */ @property (readonly, nonatomic) OFData *bitStringValue; -/*! +/** * @brief The length of the BitString in bits. */ @property (readonly, nonatomic) size_t bitStringLength; -/*! +/** * @brief Creates an ASN.1 BitString with the specified BitString value and * length. * * @param bitStringValue The value of the BitString * @param bitStringLength The length of the BitString in bits @@ -54,11 +54,11 @@ + (instancetype)bitStringWithBitStringValue: (OFData *)bitStringValue bitStringLength: (size_t)bitStringLength; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated ASN.1 BitString with the specified * BitString value and length. * * @param bitStringValue The value of the BitString * @param bitStringLength The length of the BitString in bits @@ -66,11 +66,11 @@ */ - (instancetype)initWithBitStringValue: (OFData *)bitStringValue bitStringLength: (size_t)bitStringLength OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 BitString with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1Boolean.h ================================================================== --- src/OFASN1Boolean.h +++ src/OFASN1Boolean.h @@ -19,45 +19,45 @@ #import "OFASN1DERRepresentation.h" #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @brief An ASN.1 Boolean. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1Boolean: OFObject { bool _booleanValue; } -/*! +/** * @brief The Boolean value. */ @property (readonly, nonatomic) bool booleanValue; -/*! +/** * @brief Creates an ASN.1 Boolean with the specified Boolean value. * * @param booleanValue The value of the Boolean * @return A new, autoreleased OFASN1Boolean */ + (instancetype)booleanWithBooleanValue: (bool)booleanValue; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated ASN.1 Boolean with the specified * Boolean value. * * @param booleanValue The value of the Boolean * @return An initialized OFASN1Boolean */ - (instancetype)initWithBooleanValue: (bool)booleanValue OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 Boolean with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1DERRepresentation.h ================================================================== --- src/OFASN1DERRepresentation.h +++ src/OFASN1DERRepresentation.h @@ -19,20 +19,20 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; -/*! +/** * @protocol OFASN1DERRepresentation \ * OFASN1DERRepresentation.h ObjFW/OFASN1DERRepresentation.h * * @brief A protocol implemented by classes that support encoding to ASN.1 DER * representation. */ @protocol OFASN1DERRepresentation -/*! +/** * @brief The object in ASN.1 DER representation. */ @property (readonly, nonatomic) OFData *ASN1DERRepresentation; @end OF_ASSUME_NONNULL_END Index: src/OFASN1Enumerated.h ================================================================== --- src/OFASN1Enumerated.h +++ src/OFASN1Enumerated.h @@ -18,45 +18,44 @@ #import "OFObject.h" #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @brief An ASN.1 Enumerated. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1Enumerated: OFObject { - intmax_t _integerValue; + long long _longLongValue; } -/*! +/** * @brief The integer value. */ -@property (readonly, nonatomic) intmax_t integerValue; +@property (readonly, nonatomic) long long longLongValue; -/*! +/** * @brief Creates an ASN.1 Enumerated with the specified integer value. * - * @param integerValue The integer value of the Enumerated + * @param value The `long long` value of the Enumerated * @return A new, autoreleased OFASN1Enumerated */ -+ (instancetype)enumeratedWithIntegerValue: (intmax_t)integerValue; ++ (instancetype)enumeratedWithLongLong: (long long)value; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated ASN.1 Enumerated with the specified * integer value. * - * @param integerValue The integer value of the Enumerated + * @param value The `long long` value of the Enumerated * @return An initialized OFASN1Enumerated */ -- (instancetype)initWithIntegerValue: (intmax_t)integerValue - OF_DESIGNATED_INITIALIZER; +- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 Enumerated with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1Enumerated.m ================================================================== --- src/OFASN1Enumerated.m +++ src/OFASN1Enumerated.m @@ -21,53 +21,53 @@ #import "OFData.h" #import "OFString.h" #import "OFInvalidArgumentException.h" -extern intmax_t of_asn1_der_integer_parse(const unsigned char *buffer, +extern long long of_asn1_der_integer_parse(const unsigned char *buffer, size_t length); @implementation OFASN1Enumerated -@synthesize integerValue = _integerValue; +@synthesize longLongValue = _longLongValue; -+ (instancetype)enumeratedWithIntegerValue: (intmax_t)integerValue ++ (instancetype)enumeratedWithLongLong: (long long)value { - return [[[self alloc] initWithIntegerValue: integerValue] autorelease]; + return [[[self alloc] initWithLongLong: value] autorelease]; } -- (instancetype)initWithIntegerValue: (intmax_t)integerValue +- (instancetype)initWithLongLong: (long long)value { self = [super init]; - _integerValue = integerValue; + _longLongValue = value; return self; } - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { - intmax_t integerValue; + long long value; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; - integerValue = of_asn1_der_integer_parse( + value = of_asn1_der_integer_parse( DEREncodedContents.items, DEREncodedContents.count); } @catch (id e) { [self release]; @throw e; } - return [self initWithIntegerValue: integerValue]; + return [self initWithLongLong: value]; } - (instancetype)init { OF_INVALID_INIT_METHOD @@ -83,22 +83,22 @@ if (![object isKindOfClass: [OFASN1Enumerated class]]) return false; enumerated = object; - if (enumerated->_integerValue != _integerValue) + if (enumerated->_longLongValue != _longLongValue) return false; return true; } - (uint32_t)hash { - return (uint32_t)_integerValue; + return (uint32_t)_longLongValue; } - (OFString *)description { - return [OFString stringWithFormat: @"", - _integerValue]; + return [OFString stringWithFormat: @"", + _longLongValue]; } @end Index: src/OFASN1IA5String.h ================================================================== --- src/OFASN1IA5String.h +++ src/OFASN1IA5String.h @@ -20,50 +20,50 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @brief An ASN.1 IA5String. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1IA5String: OFObject { OFString *_IA5StringValue; } -/*! +/** * @brief The IA5String value. */ @property (readonly, nonatomic) OFString *IA5StringValue; -/*! +/** * @brief The string value. */ @property (readonly, nonatomic) OFString *stringValue; -/*! +/** * @brief Creates an IA5String with the specified string value. * * @param stringValue The string value of the IA5String * @return A new, autoreleased OFASN1IA5String */ + (instancetype)stringWithStringValue: (OFString *)stringValue; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated IA5String with the specified string * value. * * @param stringValue The string value of the IA5String * @return An initialized OFASN1IA5String */ - (instancetype)initWithStringValue: (OFString *)stringValue OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 IA5String with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1Integer.h ================================================================== --- src/OFASN1Integer.h +++ src/OFASN1Integer.h @@ -18,45 +18,44 @@ #import "OFObject.h" #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @brief An ASN.1 Integer. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1Integer: OFObject { - intmax_t _integerValue; + long long _longLongValue; } -/*! +/** * @brief The Integer value. */ -@property (readonly, nonatomic) intmax_t integerValue; +@property (readonly, nonatomic) long long longLongValue; -/*! +/** * @brief Creates an ASN.1 Integer with the specified integer value. * - * @param integerValue The integer value of the Integer + * @param value The `long long` value of the Integer * @return A new, autoreleased OFASN1Integer */ -+ (instancetype)integerWithIntegerValue: (intmax_t)integerValue; ++ (instancetype)integerWithLongLong: (long long)value; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated ASN.1 Integer with the specified * integer value. * - * @param integerValue The integer value of the Integer + * @param value The `long long` value of the Integer * @return An initialized OFASN1Integer */ -- (instancetype)initWithIntegerValue: (intmax_t)integerValue - OF_DESIGNATED_INITIALIZER; +- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 Integer with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1Integer.m ================================================================== --- src/OFASN1Integer.m +++ src/OFASN1Integer.m @@ -23,73 +23,73 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" -intmax_t +long long of_asn1_der_integer_parse(const unsigned char *buffer, size_t length) { - uintmax_t value = 0; + unsigned long long value = 0; /* TODO: Support for big numbers */ - if (length > sizeof(uintmax_t) && - (length != sizeof(uintmax_t) + 1 || buffer[0] != 0)) + if (length > sizeof(unsigned long long) && + (length != sizeof(unsigned long long) + 1 || buffer[0] != 0)) @throw [OFOutOfRangeException exception]; if (length >= 2 && ((buffer[0] == 0 && !(buffer[1] & 0x80)) || (buffer[0] == 0xFF && buffer[1] & 0x80))) @throw [OFInvalidFormatException exception]; if (length >= 1 && buffer[0] & 0x80) - value = ~(uintmax_t)0; + value = ~0ull; while (length--) value = (value << 8) | *buffer++; return value; } @implementation OFASN1Integer -@synthesize integerValue = _integerValue; +@synthesize longLongValue = _longLongValue; -+ (instancetype)integerWithIntegerValue: (intmax_t)integerValue ++ (instancetype)integerWithLongLong: (long long)value { - return [[[self alloc] initWithIntegerValue: integerValue] autorelease]; + return [[[self alloc] initWithLongLong: value] autorelease]; } -- (instancetype)initWithIntegerValue: (intmax_t)integerValue +- (instancetype)initWithLongLong: (long long)value { self = [super init]; - _integerValue = integerValue; + _longLongValue = value; return self; } - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { - intmax_t integerValue; + long long value; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; - integerValue = of_asn1_der_integer_parse( + value = of_asn1_der_integer_parse( DEREncodedContents.items, DEREncodedContents.count); } @catch (id e) { [self release]; @throw e; } - return [self initWithIntegerValue: integerValue]; + return [self initWithLongLong: value]; } - (instancetype)init { OF_INVALID_INIT_METHOD @@ -105,22 +105,22 @@ if (![object isKindOfClass: [OFASN1Integer class]]) return false; integer = object; - if (integer->_integerValue != _integerValue) + if (integer->_longLongValue != _longLongValue) return false; return true; } - (uint32_t)hash { - return (uint32_t)_integerValue; + return (uint32_t)_longLongValue; } - (OFString *)description { - return [OFString stringWithFormat: @"", - _integerValue]; + return [OFString stringWithFormat: @"", + _longLongValue]; } @end Index: src/OFASN1NumericString.h ================================================================== --- src/OFASN1NumericString.h +++ src/OFASN1NumericString.h @@ -20,50 +20,50 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @brief An ASN.1 NumericString. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1NumericString: OFObject { OFString *_numericStringValue; } -/*! +/** * @brief The NumericString value. */ @property (readonly, nonatomic) OFString *numericStringValue; -/*! +/** * @brief The string value. */ @property (readonly, nonatomic) OFString *stringValue; -/*! +/** * @brief Creates an NumericString with the specified string value. * * @param stringValue The string value of the NumericString * @return A new, autoreleased OFASN1NumericString */ + (instancetype)stringWithStringValue: (OFString *)stringValue; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated NumericString with the specified * string value. * * @param stringValue The string value of the NumericString * @return An initialized OFASN1NumericString */ - (instancetype)initWithStringValue: (OFString *)stringValue OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 NumericString with the * specified arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1ObjectIdentifier.h ================================================================== --- src/OFASN1ObjectIdentifier.h +++ src/OFASN1ObjectIdentifier.h @@ -21,25 +21,25 @@ OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjetType); @class OFNumber; -/*! +/** * @brief An ASN.1 ObjectIdentifier. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1ObjectIdentifier: OFObject { OFArray OF_GENERIC(OFNumber *) *_subidentifiers; } -/*! +/** * @brief The subidentifiers of the ObjectIdentifier. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFNumber *) *subidentifiers; -/*! +/** * @brief Creates an ASN.1 ObjectIdentifier with the specified subidentifiers. * * @param subidentifiers The subidentifiers of the ASN.1 ObjectIdentifier * @return A new, autoreleased OFASN1ObjectIdentifier */ @@ -46,21 +46,21 @@ + (instancetype)objectIdentifierWithSubidentifiers: (OFArray OF_GENERIC(OFNumber *) *)subidentifiers; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated ASN.1 ObjectIdentifier with the * specified subidentifiers. * * @param subidentifiers The subidentifiers of the ASN.1 ObjectIdentifier * @return An initialized OFASN1ObjectIdentifier */ - (instancetype)initWithSubidentifiers: (OFArray OF_GENERIC(OFNumber *) *)subidentifiers OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 ObjectIdentifier with the * specified arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1ObjectIdentifier.m ================================================================== --- src/OFASN1ObjectIdentifier.m +++ src/OFASN1ObjectIdentifier.m @@ -44,11 +44,11 @@ @try { if (subidentifiers.count < 1) @throw [OFInvalidFormatException exception]; - switch ([[subidentifiers objectAtIndex: 0] intMaxValue]) { + switch ([[subidentifiers objectAtIndex: 0] longLongValue]) { case 0: case 1: case 2: break; default: @@ -73,11 +73,11 @@ OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers; @try { const unsigned char *items = DEREncodedContents.items; size_t count = DEREncodedContents.count; - uintmax_t value = 0; + unsigned long long value = 0; uint_fast8_t bits = 0; if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER || constructed) @@ -93,33 +93,33 @@ @throw [OFInvalidFormatException exception]; value = (value << 7) | (items[i] & 0x7F); bits += 7; - if (bits > sizeof(uintmax_t) * 8) + if (bits > sizeof(unsigned long long) * 8) @throw [OFOutOfRangeException exception]; if (items[i] & 0x80) continue; if (subidentifiers.count == 0) { if (value < 40) [subidentifiers addObject: - [OFNumber numberWithUIntMax: 0]]; + [OFNumber numberWithInt: 0]]; else if (value < 80) { [subidentifiers addObject: - [OFNumber numberWithUIntMax: 1]]; + [OFNumber numberWithInt: 1]]; value -= 40; } else { [subidentifiers addObject: - [OFNumber numberWithUIntMax: 2]]; + [OFNumber numberWithInt: 2]]; value -= 80; } } [subidentifiers addObject: - [OFNumber numberWithUIntMax: value]]; + [OFNumber numberWithUnsignedLongLong: value]]; value = 0; bits = 0; } Index: src/OFASN1OctetString.h ================================================================== --- src/OFASN1OctetString.h +++ src/OFASN1OctetString.h @@ -20,45 +20,45 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; -/*! +/** * @brief An ASN.1 OctetString. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1OctetString: OFObject { OFData *_octetStringValue; } -/*! +/** * @brief The OctetString value. */ @property (readonly, nonatomic) OFData *octetStringValue; -/*! +/** * @brief Creates an OctetString with the specified value. * * @param octetStringValue The OctetString value * @return A new, autoreleased OFASN1OctetString */ + (instancetype)octetStringWithOctetStringValue: (OFData *)octetStringValue; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OctetString with the specified * value. * * @param octetStringValue The OctetString value * @return An initialized OFASN1OctetString */ - (instancetype)initWithOctetStringValue: (OFData *)octetStringValue OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 OctetString with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1PrintableString.h ================================================================== --- src/OFASN1PrintableString.h +++ src/OFASN1PrintableString.h @@ -20,50 +20,50 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @brief An ASN.1 PrintableString. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1PrintableString: OFObject { OFString *_printableStringValue; } -/*! +/** * @brief The PrintableString value. */ @property (readonly, nonatomic) OFString *printableStringValue; -/*! +/** * @brief The string value. */ @property (readonly, nonatomic) OFString *stringValue; -/*! +/** * @brief Creates a PrintableString with the specified string value. * * @param stringValue The string value of the PrintableString * @return A new, autoreleased OFASN1PrintableString */ + (instancetype)stringWithStringValue: (OFString *)stringValue; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated PrintableString with the specified * string value. * * @param stringValue The string value of the PrintableString * @return An initialized OFASN1PrintableString */ - (instancetype)initWithStringValue: (OFString *)stringValue OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 PrintableString with the * specified arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1UTF8String.h ================================================================== --- src/OFASN1UTF8String.h +++ src/OFASN1UTF8String.h @@ -20,50 +20,50 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @brief An ASN.1 UTF8String. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1UTF8String: OFObject { OFString *_UTF8StringValue; } -/*! +/** * @brief The UTF8String value. */ @property (readonly, nonatomic) OFString *UTF8StringValue; -/*! +/** * @brief The string value. */ @property (readonly, nonatomic) OFString *stringValue; -/*! +/** * @brief Creates a UTF8String with the specified string value. * * @param stringValue The string value of the UTF8String * @return A new, autoreleased OFASN1UTF8String */ + (instancetype)stringWithStringValue: (OFString *)stringValue; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated UTF8String with the specified * string value. * * @param stringValue The string value of the UTF8String * @return An initialized OFASN1UTF8String */ - (instancetype)initWithStringValue: (OFString *)stringValue OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated ASN.1 UTF8String with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFASN1Value.h ================================================================== --- src/OFASN1Value.h +++ src/OFASN1Value.h @@ -17,61 +17,61 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFData; -/*! +/** * @brief ASN.1 tag class. */ typedef enum { - /*! Universal */ + /** Universal */ OF_ASN1_TAG_CLASS_UNIVERSAL = 0x0, - /*! Application */ + /** Application */ OF_ASN1_TAG_CLASS_APPLICATION = 0x1, - /*! Context specific */ + /** Context specific */ OF_ASN1_TAG_CLASS_CONTEXT_SPECIFIC = 0x2, - /*! Private */ + /** Private */ OF_ASN1_TAG_CLASS_PRIVATE = 0x3 } of_asn1_tag_class_t; -/*! +/** * @brief ASN.1 tag number. */ typedef enum { - /*! Boolean */ + /** Boolean */ OF_ASN1_TAG_NUMBER_BOOLEAN = 0x01, - /*! Integer */ + /** Integer */ OF_ASN1_TAG_NUMBER_INTEGER = 0x02, - /*! Bit string */ + /** Bit string */ OF_ASN1_TAG_NUMBER_BIT_STRING = 0x03, - /*! Octet string */ + /** Octet string */ OF_ASN1_TAG_NUMBER_OCTET_STRING = 0x04, - /*! Null */ + /** Null */ OF_ASN1_TAG_NUMBER_NULL = 0x05, - /*! Object Identifier */ + /** Object Identifier */ OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER = 0x06, - /*! Enumerated */ + /** Enumerated */ OF_ASN1_TAG_NUMBER_ENUMERATED = 0x0A, - /*! UTF-8 string */ + /** UTF-8 string */ OF_ASN1_TAG_NUMBER_UTF8_STRING = 0x0C, - /*! Sequence */ + /** Sequence */ OF_ASN1_TAG_NUMBER_SEQUENCE = 0x10, - /*! Set */ + /** Set */ OF_ASN1_TAG_NUMBER_SET = 0x11, - /*! NumericString */ + /** NumericString */ OF_ASN1_TAG_NUMBER_NUMERIC_STRING = 0x12, - /*! PrintableString */ + /** PrintableString */ OF_ASN1_TAG_NUMBER_PRINTABLE_STRING = 0x13, - /*! IA5String */ + /** IA5String */ OF_ASN1_TAG_NUMBER_IA5_STRING = 0x16 } of_asn1_tag_number_t; -/*! +/** * @brief A class representing an ASN.1 value. */ OF_SUBCLASSING_RESTRICTED @interface OFASN1Value: OFObject { @@ -79,31 +79,31 @@ of_asn1_tag_number_t _tagNumber; bool _constructed; OFData *_DEREncodedContents; } -/*! +/** * @brief The tag class of the value's type. */ @property (readonly, nonatomic) of_asn1_tag_class_t tagClass; -/*! +/** * @brief The tag number of the value's type. */ @property (readonly, nonatomic) of_asn1_tag_number_t tagNumber; -/*! +/** * @brief Whether the value if of a constructed type. */ @property (readonly, nonatomic, getter=isConstructed) bool constructed; -/*! +/** * @brief The DER-encoded contents octets of the value. */ @property (readonly, nonatomic) OFData *DEREncodedContents; -/*! +/** * @brief Creates a new ASN.1 value with the specified arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type * @param constructed Whether the value if of a constructed type @@ -115,11 +115,11 @@ constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated ASN.1 value with the specified * arguments. * * @param tagClass The tag class of the value's type * @param tagNumber The tag number of the value's type Index: src/OFApplication.h ================================================================== --- src/OFApplication.h +++ src/OFApplication.h @@ -19,20 +19,20 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFSandbox; @class OFString; -/*! +/** * @brief Specify the class to be used as the application delegate. * * An instance of this class will be created and act as the application * delegate. * @@ -64,31 +64,31 @@ #ifdef OF_HAVE_PLEDGE # define OF_HAVE_SANDBOX #endif -/*! +/** * @protocol OFApplicationDelegate OFApplication.h ObjFW/OFApplication.h * * @brief A protocol for delegates of OFApplication. * * @note Signals are not available on AmigaOS! */ @protocol OFApplicationDelegate -/*! +/** * @brief A method which is called when the application was initialized and is * running now. */ - (void)applicationDidFinishLaunching; @optional -/*! +/** * @brief A method which is called when the application will terminate. */ - (void)applicationWillTerminate; -/*! +/** * @brief A method which is called when the application received a SIGINT. * * @warning You are not allowed to send any messages inside this method, as * message dispatching is not signal-safe! You are only allowed to do * signal-safe operations like setting a variable or calling a @@ -95,11 +95,11 @@ * signal-safe function! */ - (void)applicationDidReceiveSIGINT; #ifdef SIGHUP -/*! +/** * @brief A method which is called when the application received a SIGHUP. * * This signal is not available on Windows. * * @warning You are not allowed to send any messages inside this method, as @@ -109,11 +109,11 @@ */ - (void)applicationDidReceiveSIGHUP; #endif #ifdef SIGUSR1 -/*! +/** * @brief A method which is called when the application received a SIGUSR1. * * This signal is not available on Windows. * * @warning You are not allowed to send any messages inside this method, as @@ -123,11 +123,11 @@ */ - (void)applicationDidReceiveSIGUSR1; #endif #ifdef SIGUSR2 -/*! +/** * @brief A method which is called when the application received a SIGUSR2. * * This signal is not available on Windows. * * @warning You are not allowed to send any messages inside this method, as @@ -137,11 +137,11 @@ */ - (void)applicationDidReceiveSIGUSR2; #endif @end -/*! +/** * @class OFApplication OFApplication.h ObjFW/OFApplication.h * * @brief A class which represents the application as an object. * * In order to create a new OFApplication, you should create a class conforming @@ -177,87 +177,87 @@ OFArray OF_GENERIC(OFString *) *arguments; @property (class, readonly, nullable, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *environment; #endif -/*! +/** * @brief The name of the program (argv[0]). */ @property (readonly, nonatomic) OFString *programName; -/*! +/** * @brief The arguments passed to the application. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *arguments; -/*! +/** * @brief The environment of the application. */ @property (readonly, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *environment; -/*! +/** * @brief The delegate of the application. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; #ifdef OF_HAVE_SANDBOX -/*! +/** * @brief The sandbox currently active for this application. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFSandbox *activeSandbox; -/*! +/** * @brief The sandbox currently active for child processes of this application. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFSandbox *activeSandboxForChildProcesses; #endif -/*! +/** * @brief Returns the only OFApplication instance in the application. * * @return The only OFApplication instance in the application */ + (nullable OFApplication *)sharedApplication; -/*! +/** * @brief Returns the name of the program (argv[0]). * * @return The name of the program (argv[0]) */ + (nullable OFString *)programName; -/*! +/** * @brief Returns the arguments passed to the application. * * @return The arguments passed to the application */ + (nullable OFArray OF_GENERIC(OFString *) *)arguments; -/*! +/** * @brief Returns the environment of the application. * * @return The environment of the application */ + (nullable OFDictionary OF_GENERIC(OFString *, OFString *) *)environment; -/*! +/** * @brief Terminates the application with the EXIT_SUCCESS status. */ + (void)terminate OF_NO_RETURN; -/*! +/** * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ + (void)terminateWithStatus: (int)status OF_NO_RETURN; #ifdef OF_HAVE_SANDBOX -/*! +/** * @brief Activates the specified sandbox for the application. * * This is only available if `OF_HAVE_SANDBOX` is defined. * * @warning If you allow `exec()`, but do not call @@ -269,11 +269,11 @@ * * @param sandbox The sandbox to activate */ + (void)activateSandbox: (OFSandbox *)sandbox; -/*! +/** * @brief Activates the specified sandbox for child processes of the * application. * * This is only available if `OF_HAVE_SANDBOX` is defined. * @@ -288,33 +288,33 @@ + (void)activateSandboxForChildProcesses: (OFSandbox *)sandbox; #endif - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Gets argc and argv. * * @param argc A pointer where a pointer to argc should be stored * @param argv A pointer where a pointer to argv should be stored */ - (void)getArgumentCount: (int *_Nonnull *_Nonnull)argc andArgumentValues: (char *_Nullable *_Nonnull *_Nonnull[_Nonnull])argv; -/*! +/** * @brief Terminates the application. */ - (void)terminate OF_NO_RETURN; -/*! +/** * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ - (void)terminateWithStatus: (int)status OF_NO_RETURN; #ifdef OF_HAVE_SANDBOX -/*! +/** * @brief Activates the specified sandbox for the application. * * This is only available if `OF_HAVE_SANDBOX` is defined. * * @warning If you allow `exec()`, but do not call @@ -326,11 +326,11 @@ * * @param sandbox The sandbox to activate */ - (void)activateSandbox: (OFSandbox *)sandbox; -/*! +/** * @brief Activates the specified sandbox for child processes of the * application. * * This is only available if `OF_HAVE_SANDBOX` is defined. * Index: src/OFArray.h ================================================================== --- src/OFArray.h +++ src/OFArray.h @@ -31,21 +31,21 @@ #import "OFJSONRepresentation.h" #import "OFMessagePackRepresentation.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFString; enum { OF_ARRAY_SKIP_EMPTY = 1, OF_ARRAY_SORT_DESCENDING = 2 }; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for enumerating an OFArray. * * @param object The current object * @param index The index of the current object * @param stop A pointer to a variable that can be set to true to stop the @@ -52,39 +52,39 @@ * enumeration */ typedef void (^of_array_enumeration_block_t)(id object, size_t index, bool *stop); -/*! +/** * @brief A block for filtering an OFArray. * * @param object The object to inspect * @param index The index of the object to inspect * @return Whether the object should be in the filtered array */ typedef bool (^of_array_filter_block_t)(id object, size_t index); -/*! +/** * @brief A block for mapping objects to objects in an OFArray. * * @param object The object to map * @param index The index of the object to map * @return The object to map to */ typedef id _Nonnull (^of_array_map_block_t)(id object, size_t index); -/*! +/** * @brief A block for folding an OFArray. * * @param left The object to which the object has been folded so far * @param right The object that should be added to the left object * @return The left and right side folded into one object */ typedef id _Nullable (^of_array_fold_block_t)(id _Nullable left, id right); #endif -/*! +/** * @class OFArray OFArray.h ObjFW/OFArray.h * * @brief An abstract class for storing objects in an array. * * @note Subclasses must implement @ref count and @ref objectAtIndex:. @@ -93,78 +93,78 @@ OFMutableCopying, OFCollection, OFSerialization, OFJSONRepresentation, OFMessagePackRepresentation> #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif -/*! +/** * @brief The objects of the array as a C array. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) ObjectType const __unsafe_unretained _Nonnull *_Nonnull objects; -/*! +/** * @brief The first object of the array or `nil`. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) ObjectType firstObject; -/*! +/** * @brief The last object of the array or `nil`. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) ObjectType lastObject; -/*! +/** * @brief The array sorted in ascending order. */ @property (readonly, nonatomic) OFArray OF_GENERIC(ObjectType) *sortedArray; -/*! +/** * @brief The array with the order reversed. */ @property (readonly, nonatomic) OFArray OF_GENERIC(ObjectType) *reversedArray; -/*! +/** * @brief Creates a new OFArray. * * @return A new autoreleased OFArray */ + (instancetype)array; -/*! +/** * @brief Creates a new OFArray with the specified object. * * @param object An object * @return A new autoreleased OFArray */ + (instancetype)arrayWithObject: (ObjectType)object; -/*! +/** * @brief Creates a new OFArray with the specified objects, terminated by `nil`. * * @param firstObject The first object in the array * @return A new autoreleased OFArray */ + (instancetype)arrayWithObjects: (ObjectType)firstObject, ... OF_SENTINEL; -/*! +/** * @brief Creates a new OFArray with the objects from the specified array. * * @param array An array * @return A new autoreleased OFArray */ + (instancetype)arrayWithArray: (OFArray OF_GENERIC(ObjectType) *)array; -/*! +/** * @brief Creates a new OFArray with the objects from the specified C array of * the specified length. * * @param objects A C array of objects * @param count The length of the C array @@ -172,45 +172,45 @@ */ + (instancetype) arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; -/*! +/** * @brief Initializes an OFArray with the specified object. * * @param object An object * @return An initialized OFArray */ - (instancetype)initWithObject: (ObjectType)object; -/*! +/** * @brief Initializes an OFArray with the specified objects. * * @param firstObject The first object * @return An initialized OFArray */ - (instancetype)initWithObjects: (ObjectType)firstObject, ... OF_SENTINEL; -/*! +/** * @brief Initializes an OFArray with the specified object and a va_list. * * @param firstObject The first object * @param arguments A va_list * @return An initialized OFArray */ - (instancetype)initWithObject: (ObjectType)firstObject arguments: (va_list)arguments; -/*! +/** * @brief Initializes an OFArray with the objects from the specified array. * * @param array An array * @return An initialized OFArray */ - (instancetype)initWithArray: (OFArray OF_GENERIC(ObjectType) *)array; -/*! +/** * @brief Initializes an OFArray with the objects from the specified C array of * the specified length. * * @param objects A C array of objects * @param count The length of the C array @@ -217,11 +217,11 @@ * @return An initialized OFArray */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; -/*! +/** * @brief Returns the object at the specified index in the array. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! * @@ -229,11 +229,11 @@ * @return The object at the specified index in the array */ - (ObjectType)objectAtIndex: (size_t)index; - (ObjectType)objectAtIndexedSubscript: (size_t)index; -/*! +/** * @brief Returns the value for the specified key * * A new array with the value for the specified key for each object is * returned. * @@ -244,11 +244,11 @@ * @param key The key of the value to return * @return The value for the specified key */ - (nullable id)valueForKey: (OFString *)key; -/*! +/** * @brief Set the value for the specified key * * @ref setValue:forKey: is called for each object in the array. * * @note A @ref OFNull value is translated to nil! @@ -257,75 +257,75 @@ * @param key The key of the value to set */ - (void)setValue: (nullable id)value forKey: (OFString *)key; -/*! +/** * @brief Copies the objects at the specified range to the specified buffer. * * @param buffer The buffer to copy the objects to * @param range The range to copy */ - (void)getObjects: (ObjectType __unsafe_unretained _Nonnull *_Nonnull)buffer inRange: (of_range_t)range; -/*! +/** * @brief Returns the index of the first object that is equivalent to the * specified object or `OF_NOT_FOUND` if it was not found. * * @param object The object whose index is returned * @return The index of the first object equivalent to the specified object * or `OF_NOT_FOUND` if it was not found */ - (size_t)indexOfObject: (ObjectType)object; -/*! +/** * @brief Returns the index of the first object that has the same address as the * specified object or `OF_NOT_FOUND` if it was not found. * * @param object The object whose index is returned * @return The index of the first object that has the same address as * the specified object or `OF_NOT_FOUND` if it was not found */ - (size_t)indexOfObjectIdenticalTo: (ObjectType)object; -/*! +/** * @brief Checks whether the array contains an object equal to the specified * object. * * @param object The object which is checked for being in the array * @return A boolean whether the array contains the specified object */ - (bool)containsObject: (ObjectType)object; -/*! +/** * @brief Checks whether the array contains an object with the specified * address. * * @param object The object which is checked for being in the array * @return A boolean whether the array contains an object with the specified * address */ - (bool)containsObjectIdenticalTo: (ObjectType)object; -/*! +/** * @brief Returns the objects in the specified range as a new OFArray. * * @param range The range for the subarray * @return The subarray as a new autoreleased OFArray */ - (OFArray OF_GENERIC(ObjectType) *)objectsInRange: (of_range_t)range; -/*! +/** * @brief Creates a string by joining all objects of the array. * * @param separator The string with which the objects should be joined * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator; -/*! +/** * @brief Creates a string by joining all objects of the array. * * @param separator The string with which the objects should be joined * @param options Options according to which the objects should be joined.@n * Possible values are: @@ -335,11 +335,11 @@ * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator options: (int)options; -/*! +/** * @brief Creates a string by calling the selector on all objects of the array * and joining the strings returned by calling the selector. * * @param separator The string with which the objects should be joined * @param selector The selector to perform on the objects @@ -346,11 +346,11 @@ * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator usingSelector: (SEL)selector; -/*! +/** * @brief Creates a string by calling the selector on all objects of the array * and joining the strings returned by calling the selector. * * @param separator The string with which the objects should be joined * @param selector The selector to perform on the objects @@ -363,18 +363,18 @@ */ - (OFString *)componentsJoinedByString: (OFString *)separator usingSelector: (SEL)selector options: (int)options; -/*! +/** * @brief Performs the specified selector on all objects in the array. * * @param selector The selector to perform on all objects in the array */ - (void)makeObjectsPerformSelector: (SEL)selector; -/*! +/** * @brief Performs the specified selector on all objects in the array with the * specified object. * * @param selector The selector to perform on all objects in the array * @param object The object to perform the selector with on all objects in the @@ -381,11 +381,11 @@ * array */ - (void)makeObjectsPerformSelector: (SEL)selector withObject: (nullable id)object; -/*! +/** * @brief Returns a copy of the array sorted using the specified selector and * options. * * @param selector The selector to use to sort the array. It's signature * should be the same as that of -[compare:]. @@ -398,11 +398,11 @@ */ - (OFArray OF_GENERIC(ObjectType) *)sortedArrayUsingSelector: (SEL)selector options: (int)options; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Returns a copy of the array sorted using the specified selector and * options. * * @param comparator The comparator to use to sort the array * @param options The options to use when sorting the array.@n @@ -415,52 +415,52 @@ - (OFArray OF_GENERIC(ObjectType) *) sortedArrayUsingComparator: (of_comparator_t)comparator options: (int)options; #endif -/*! +/** * @brief Creates a new array with the specified object added. * * @param object The object to add * @return A new array with the specified object added */ - (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObject: (ObjectType)object; -/*! +/** * @brief Creates a new array with the objects from the specified array added. * * @param array The array with objects to add * @return A new array with the objects from the specified array added */ - (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array; -/*! +/** * @brief Creates a new array with the specified object removed. * * @param object The object to remove * @return A new array with the specified object removed */ - (OFArray OF_GENERIC(ObjectType) *)arrayByRemovingObject: (ObjectType)object; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Executes a block for each object. * * @param block The block to execute for each object */ - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block; -/*! +/** * @brief Creates a new array, mapping each object using the specified block. * * @param block A block which maps an object for each object * @return A new, autoreleased OFArray */ - (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block; -/*! +/** * @brief Creates a new array, only containing the objects for which the block * returns true. * * @param block A block which determines if the object should be in the new * array @@ -467,11 +467,11 @@ * @return A new, autoreleased OFArray */ - (OFArray OF_GENERIC(ObjectType) *)filteredArrayUsingBlock: (of_array_filter_block_t)block; -/*! +/** * @brief Folds the array to a single object using the specified block. * * If the array is empty, it will return `nil`. * * If there is only one object in the array, that object will be returned and Index: src/OFBlock.h ================================================================== --- src/OFBlock.h +++ src/OFBlock.h @@ -19,11 +19,11 @@ #import "block.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFBlock OFBlock.h ObjFW/OFBlock.h * * @brief The class for all blocks, since all blocks are also objects. */ @interface OFBlock: OFObject Index: src/OFCharacterSet.h ================================================================== --- src/OFCharacterSet.h +++ src/OFCharacterSet.h @@ -18,75 +18,75 @@ #import "OFObject.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFCharacterSet OFCharacterSet.h ObjFW/OFCharacterSet.h * * @brief A class cluster representing a character set. * * @note Subclasses must implement @ref characterIsMember:. */ @interface OFCharacterSet: OFObject { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFCharacterSet, 4) } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFCharacterSet *whitespaceCharacterSet; #endif -/*! +/** * @brief The inverted set, containing only the characters that do not exist in * the receiver. */ @property (readonly, nonatomic) OFCharacterSet *invertedSet; -/*! +/** * @brief Creates a new character set containing the characters of the * specified string. * * @param characters The characters for the character set * @return A new OFCharacterSet */ + (instancetype)characterSetWithCharactersInString: (OFString *)characters; -/*! +/** * @brief Creates a new character set containing the characters in the specified * range. * * @param range The range of characters for the character set * @return A new OFCharacterSet */ + (instancetype)characterSetWithRange: (of_range_t)range; -/*! +/** * @brief A character set containing all Unicode characters in the category * `Zs` plus CHARACTER TABULATION (U+0009). */ + (OFCharacterSet *)whitespaceCharacterSet; -/*! +/** * @brief Initializes an already allocated character set with the characters of * the specified string. * * @param characters The characters for the character set * @return An initialized OFCharacterSet */ - (instancetype)initWithCharactersInString: (OFString *)characters; -/*! +/** * @brief Initializes an already allocated character set with the characters in * the specified range. * * @param range The range of characters for the character set * @return An initialized OFCharacterSet */ - (instancetype)initWithRange: (of_range_t)range; -/*! +/** * @brief Returns whether the specified character is a member of the character * set. * * @param character The character that is checked for being a member of the * character set Index: src/OFCollection.h ================================================================== --- src/OFCollection.h +++ src/OFCollection.h @@ -17,22 +17,22 @@ #import "OFEnumerator.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @protocol OFCollection OFCollection.h ObjFW/OFCollection.h * * @brief A protocol with methods common for all collections. */ @protocol OFCollection -/*! +/** * @brief The number of objects in the collection */ @property (readonly, nonatomic) size_t count; -/*! +/** * @brief Checks whether the collection contains an object equal to the * specified object. * * @param object The object which is checked for being in the collection * @return A boolean whether the collection contains the specified object Index: src/OFColor.h ================================================================== --- src/OFColor.h +++ src/OFColor.h @@ -17,19 +17,19 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFColor OFColor.h ObjFW/OFColor.h * * @brief A class for storing a color. */ @interface OFColor: OFObject { float _red, _green, _blue, _alpha; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFColor, 4) } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFColor *black; @property (class, readonly, nonatomic) OFColor *silver; @@ -47,11 +47,11 @@ @property (class, readonly, nonatomic) OFColor *blue; @property (class, readonly, nonatomic) OFColor *teal; @property (class, readonly, nonatomic) OFColor *aqua; #endif -/*! +/** * @brief Creates a new color with the specified red, green, blue and alpha * value. * * @param red The red value of the color, between 0.0 and 1.0 * @param green The green value of the color, between 0.0 and 1.0 @@ -62,155 +62,155 @@ + (instancetype)colorWithRed: (float)red green: (float)green blue: (float)blue alpha: (float)alpha; -/*! +/** * @brief Returns the HTML color `black`. * * The RGBA value is (0, 0, 0, 1). * * @return The HTML color `black` */ + (OFColor *)black; -/*! +/** * @brief Returns the HTML color `silver`. * * The RGBA value is (0.75, 0.75, 0.75, 1). * * @return The HTML color `silver` */ + (OFColor *)silver; -/*! +/** * @brief Returns the HTML color `grey`. * * The RGBA value is (0.5, 0.5, 0.5, 1). * * @return The HTML color `grey` */ + (OFColor *)grey; -/*! +/** * @brief Returns the HTML color `white`. * * The RGBA value is (1, 1, 1, 1). * * @return The HTML color `white` */ + (OFColor *)white; -/*! +/** * @brief Returns the HTML color `maroon`. * * The RGBA value is (0.5, 0, 0, 1). * * @return The HTML color `maroon` */ + (OFColor *)maroon; -/*! +/** * @brief Returns the HTML color `red`. * * The RGBA value is (1, 0, 0, 1). * * @return The HTML color `red` */ + (OFColor *)red; -/*! +/** * @brief Returns the HTML color `purple`. * * The RGBA value is (0.5, 0, 0.5, 1). * * @return The HTML color `purple` */ + (OFColor *)purple; -/*! +/** * @brief Returns the HTML color `fuchsia`. * * The RGBA value is (1, 0, 1, 1). * * @return The HTML color `fuchsia` */ + (OFColor *)fuchsia; -/*! +/** * @brief Returns the HTML color `green`. * * The RGBA value is (0, 0.5, 0, 1). * * @return The HTML color `green` */ + (OFColor *)green; -/*! +/** * @brief Returns the HTML color `lime`. * * The RGBA value is (0, 1, 0, 1). * * @return The HTML color `lime` */ + (OFColor *)lime; -/*! +/** * @brief Returns the HTML color `olive`. * * The RGBA value is (0.5, 0.5, 0, 1). * * @return The HTML color `olive` */ + (OFColor *)olive; -/*! +/** * @brief Returns the HTML color `yellow`. * * The RGBA value is (1, 1, 0, 1). * * @return The HTML color `yellow` */ + (OFColor *)yellow; -/*! +/** * @brief Returns the HTML color `navy`. * * The RGBA value is (0, 0, 0.5, 1). * * @return The HTML color `navy` */ + (OFColor *)navy; -/*! +/** * @brief Returns the HTML color `blue`. * * The RGBA value is (0, 0, 1, 1). * * @return The HTML color `blue` */ + (OFColor *)blue; -/*! +/** * @brief Returns the HTML color `teal`. * * The RGBA value is (0, 0.5, 0.5, 1). * * @return The HTML color `teal` */ + (OFColor *)teal; -/*! +/** * @brief Returns the HTML color `aqua`. * * The RGBA value is (0, 1, 1, 1). * * @return The HTML color `aqua` */ + (OFColor *)aqua; -/*! +/** * @brief Initializes an already allocated color with the specified red, green, * blue and alpha value. * * @param red The red value of the color, between 0.0 and 1.0 * @param green The green value of the color, between 0.0 and 1.0 @@ -222,11 +222,11 @@ - (instancetype)initWithRed: (float)red green: (float)green blue: (float)blue alpha: (float)alpha; -/*! +/** * @brief Returns the red, green, blue and alpha value of the color. * * @param red A pointer to store the red value of the color * @param green A pointer to store the green value of the color * @param blue A pointer to store the blue value of the color Index: src/OFColor.m ================================================================== --- src/OFColor.m +++ src/OFColor.m @@ -42,26 +42,26 @@ of_once(&onceControl, initPredefinedColor_##name); \ \ return name##Color; \ } -PREDEFINED_COLOR(black, 0.00, 0.00, 0.00) -PREDEFINED_COLOR(silver, 0.75, 0.75, 0.75) -PREDEFINED_COLOR(grey, 0.50, 0.50, 0.50) -PREDEFINED_COLOR(white, 1.00, 1.00, 1.00) -PREDEFINED_COLOR(maroon, 0.50, 0.00, 0.00) -PREDEFINED_COLOR(red, 1.00, 0.00, 0.00) -PREDEFINED_COLOR(purple, 0.50, 0.00, 0.50) -PREDEFINED_COLOR(fuchsia, 1.00, 0.00, 1.00) -PREDEFINED_COLOR(green, 0.00, 0.50, 0.00) -PREDEFINED_COLOR(lime, 0.00, 1.00, 0.00) -PREDEFINED_COLOR(olive, 0.50, 0.50, 0.00) -PREDEFINED_COLOR(yellow, 1.00, 1.00, 0.00) -PREDEFINED_COLOR(navy, 0.00, 0.00, 0.50) -PREDEFINED_COLOR(blue, 0.00, 0.00, 1.00) -PREDEFINED_COLOR(teal, 0.00, 0.50, 0.50) -PREDEFINED_COLOR(aqua, 0.00, 1.00, 1.00) +PREDEFINED_COLOR(black, 0.00f, 0.00f, 0.00f) +PREDEFINED_COLOR(silver, 0.75f, 0.75f, 0.75f) +PREDEFINED_COLOR(grey, 0.50f, 0.50f, 0.50f) +PREDEFINED_COLOR(white, 1.00f, 1.00f, 1.00f) +PREDEFINED_COLOR(maroon, 0.50f, 0.00f, 0.00f) +PREDEFINED_COLOR(red, 1.00f, 0.00f, 0.00f) +PREDEFINED_COLOR(purple, 0.50f, 0.00f, 0.50f) +PREDEFINED_COLOR(fuchsia, 1.00f, 0.00f, 1.00f) +PREDEFINED_COLOR(green, 0.00f, 0.50f, 0.00f) +PREDEFINED_COLOR(lime, 0.00f, 1.00f, 0.00f) +PREDEFINED_COLOR(olive, 0.50f, 0.50f, 0.00f) +PREDEFINED_COLOR(yellow, 1.00f, 1.00f, 0.00f) +PREDEFINED_COLOR(navy, 0.00f, 0.00f, 0.50f) +PREDEFINED_COLOR(blue, 0.00f, 0.00f, 1.00f) +PREDEFINED_COLOR(teal, 0.00f, 0.50f, 0.50f) +PREDEFINED_COLOR(aqua, 0.00f, 1.00f, 1.00f) + (instancetype)colorWithRed: (float)red green: (float)green blue: (float)blue alpha: (float)alpha Index: src/OFCondition.h ================================================================== --- src/OFCondition.h +++ src/OFCondition.h @@ -21,11 +21,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFDate; -/*! +/** * @class OFCondition OFCondition.h ObjFW/OFCondition.h * * @brief A class implementing a condition variable for thread synchronization. */ OF_SUBCLASSING_RESTRICTED @@ -33,28 +33,28 @@ { of_condition_t _condition; bool _conditionInitialized; } -/*! +/** * @brief Creates a new condition. * * @return A new, autoreleased OFCondition */ + (instancetype)condition; -/*! +/** * @brief Blocks the current thread until another thread calls @ref signal or * @ref broadcast. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref wait returned! */ - (void)wait; #ifdef OF_AMIGAOS -/*! +/** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or an Exec Signal is received. * * @note This is only available on AmigaOS! * @@ -62,11 +62,11 @@ * This is modified and set to the mask of signals received. */ - (void)waitForConditionOrExecSignal: (ULONG *)signalMask; #endif -/*! +/** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitForTimeInterval: returned! @@ -75,11 +75,11 @@ * @return Whether the condition has been signaled */ - (bool)waitForTimeInterval: (of_time_interval_t)timeInterval; #ifdef OF_AMIGAOS -/*! +/** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * @@ -90,11 +90,11 @@ */ - (bool)waitForTimeInterval: (of_time_interval_t)timeInterval orExecSignal: (ULONG *)signalMask; #endif -/*! +/** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitUntilDate: returned! @@ -103,11 +103,11 @@ * @return Whether the condition has been signaled */ - (bool)waitUntilDate: (OFDate *)date; #ifdef OF_AMIGAOS -/*! +/** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * @@ -118,17 +118,17 @@ */ - (bool)waitUntilDate: (OFDate *)date orExecSignal: (ULONG *)signalMask; #endif -/*! +/** * @brief Signals the next waiting thread to continue. */ - (void)signal; -/*! +/** * @brief Signals all threads to continue. */ - (void)broadcast; @end OF_ASSUME_NONNULL_END Index: src/OFConstantString.h ================================================================== --- src/OFConstantString.h +++ src/OFConstantString.h @@ -32,11 +32,11 @@ } # endif #endif #ifdef __OBJC__ -/*! +/** * @class OFConstantString OFConstantString.h ObjFW/OFConstantString.h * * @brief A class for storing constant strings using the `@""` literal. */ OF_SUBCLASSING_RESTRICTED Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -573,29 +573,36 @@ [self finishInitialization]; return self.stringByDeletingLastPathComponent; } -- (intmax_t)decimalValue +- (long long)longLongValue +{ + [self finishInitialization]; + + return self.longLongValue; +} + +- (long long)longLongValueWithBase: (int)base +{ + [self finishInitialization]; + + return [self longLongValueWithBase: base]; +} + +- (unsigned long long)unsignedLongLongValue { [self finishInitialization]; - return self.decimalValue; + return self.unsignedLongLongValue; } -- (uintmax_t)hexadecimalValue +- (unsigned long long)unsignedLongLongValueWithBase: (int)base { [self finishInitialization]; - return self.hexadecimalValue; -} - -- (uintmax_t)octalValue -{ - [self finishInitialization]; - - return self.octalValue; + return [self unsignedLongLongValueWithBase: base]; } - (float)floatValue { [self finishInitialization]; Index: src/OFCountedMapTableSet.m ================================================================== --- src/OFCountedMapTableSet.m +++ src/OFCountedMapTableSet.m @@ -136,26 +136,21 @@ [element elementsForName: @"object" namespace: OF_SERIALIZATION_NS]) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *object; OFXMLAttribute *countAttribute; - intmax_t signedCount; - uintmax_t count; + unsigned long long count; object = [objectElement elementsForNamespace: OF_SERIALIZATION_NS].firstObject; countAttribute = [objectElement attributeForName: @"count"]; if (object == nil || countAttribute == nil) @throw [OFInvalidFormatException exception]; - signedCount = countAttribute.decimalValue; - if (signedCount < 0) - @throw [OFOutOfRangeException exception]; - - count = signedCount; + count = countAttribute.unsignedLongLongValue; if (count > SIZE_MAX || count > UINTPTR_MAX) @throw [OFOutOfRangeException exception]; [_mapTable setObject: (void *)(uintptr_t)count forKey: object.objectByDeserializing]; Index: src/OFCountedSet.h ================================================================== --- src/OFCountedSet.h +++ src/OFCountedSet.h @@ -17,14 +17,14 @@ #import "OFSet.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for enumerating an OFCountedSet. * * @param object The current object * @param count The count of the object * @param stop A pointer to a variable that can be set to true to stop the @@ -32,11 +32,11 @@ */ typedef void (^of_counted_set_enumeration_block_t)(id object, size_t count, bool *stop); #endif -/*! +/** * @class OFCountedSet OFCountedSet.h ObjFW/OFCountedSet.h * * @brief An abstract class for a mutable unordered set of objects, counting how * often it contains an object. * @@ -46,19 +46,19 @@ @interface OFCountedSet OF_GENERIC(ObjectType): OFMutableSet OF_GENERIC(ObjectType) #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif -/*! +/** * @brief Returns how often the object is in the set. * * @return How often the object is in the set */ - (size_t)countForObject: (ObjectType)object; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Executes a block for each object in the set. * * @param block The block to execute for each object in the set */ - (void)enumerateObjectsAndCountUsingBlock: Index: src/OFCryptoHash.h ================================================================== --- src/OFCryptoHash.h +++ src/OFCryptoHash.h @@ -17,11 +17,11 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @protocol OFCryptoHash OFCryptoHash.h ObjFW/OFCryptoHash.h * * @brief A protocol for classes providing cryptographic hash functions. * * A cryptographic hash implementing this protocol can be copied. The entire @@ -32,80 +32,80 @@ #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) size_t digestSize; @property (class, readonly, nonatomic) size_t blockSize; #endif -/*! +/** * @brief The digest size of the cryptographic hash, in bytes. */ @property (readonly, nonatomic) size_t digestSize; -/*! +/** * @brief The block size of the cryptographic hash, in bytes. */ @property (readonly, nonatomic) size_t blockSize; -/*! +/** * @brief Whether data may be stored in swappable memory. */ @property (readonly, nonatomic) bool allowsSwappableMemory; -/*! +/** * @brief A boolean whether the hash has already been calculated. */ @property (readonly, nonatomic, getter=isCalculated) bool calculated; -/*! +/** * @brief A buffer containing the cryptographic hash. * * The size of the buffer depends on the hash used. The buffer is part of the * receiver's memory pool. */ @property (readonly, nonatomic) const unsigned char *digest OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Creates a new cryptographic hash. * * @return A new autoreleased cryptographic hash */ + (instancetype)cryptoHashWithAllowsSwappableMemory: (bool)allowsSwappableMemory; -/*! +/** * @brief Returns the digest size of the cryptographic hash, in bytes. * * @return The digest size of the cryptographic hash, in bytes */ + (size_t)digestSize; -/*! +/** * @brief Returns the block size of the cryptographic hash, in bytes. * * @return The block size of the cryptographic hash, in bytes */ + (size_t)blockSize; -/*! +/** * @brief Initializes an already allocated cryptographic hash. * * @return An initialized cryptographic hash */ - (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Adds a buffer to the cryptographic hash to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; -/*! +/** * @brief Resets all state so that a new hash can be calculated. * * @warning This invalidates any pointer previously returned by @ref digest. If * you are still interested in the previous digest, you need to memcpy * it yourself before calling @ref reset! Index: src/OFDNSQuery.h ================================================================== --- src/OFDNSQuery.h +++ src/OFDNSQuery.h @@ -20,39 +20,39 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @class OFDNSQuery OFDNSQuery.h ObjFW/OFDNSQuery.h * * @brief A class representing a DNS query. */ @interface OFDNSQuery: OFObject { OFString *_domainName; of_dns_class_t _DNSClass; of_dns_record_type_t _recordType; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFDNSQuery, 4) } -/*! +/** * @brief The domain name of the query. */ @property (readonly, nonatomic) OFString *domainName; -/*! +/** * @brief The DNS class of the query. */ @property (readonly, nonatomic) of_dns_class_t DNSClass; -/*! +/** * @brief The record type of the query. */ @property (readonly, nonatomic) of_dns_record_type_t recordType; -/*! +/** * @brief Creates a new, autoreleased OFDNSQuery. * * @param domainName The domain name to query * @param DNSClass The DNS class of the query * @param recordType The record type of the query @@ -60,11 +60,11 @@ */ + (instancetype)queryWithDomainName: (OFString *)domainName DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType; -/*! +/** * @brief Initializes an already allocated OFDNSQuery. * * @param domainName The domain name to query * @param DNSClass The DNS class of the query * @param recordType The record type of the query Index: src/OFDNSResolver.h ================================================================== --- src/OFDNSResolver.h +++ src/OFDNSResolver.h @@ -35,50 +35,50 @@ @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFNumber; @class OFTCPSocket; @class OFUDPSocket; -/*! +/** * @enum of_dns_resolver_error_t OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief An enum describing why resolving a host failed. */ typedef enum of_dns_resolver_error_t { - /*! An unknown error */ + /** An unknown error */ OF_DNS_RESOLVER_ERROR_UNKNOWN, - /*! The query timed out */ + /** The query timed out */ OF_DNS_RESOLVER_ERROR_TIMEOUT, - /*! The query was canceled */ + /** The query was canceled */ OF_DNS_RESOLVER_ERROR_CANCELED, - /*! + /** * No result for the specified host with the specified type and class. * * This is only used in situations where this is an error, e.g. when * trying to connect to a host. */ OF_DNS_RESOLVER_ERROR_NO_RESULT, - /*! The server considered the query to be malformed */ + /** The server considered the query to be malformed */ OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT, - /*! The server was unable to process due to an internal error */ + /** The server was unable to process due to an internal error */ OF_DNS_RESOLVER_ERROR_SERVER_FAILURE, - /*! The server returned an error that the domain does not exist */ + /** The server returned an error that the domain does not exist */ OF_DNS_RESOLVER_ERROR_SERVER_NAME_ERROR, - /*! The server does not have support for the requested query */ + /** The server does not have support for the requested query */ OF_DNS_RESOLVER_ERROR_SERVER_NOT_IMPLEMENTED, - /*! The server refused the query */ + /** The server refused the query */ OF_DNS_RESOLVER_ERROR_SERVER_REFUSED, - /*! There was no name server to query */ + /** There was no name server to query */ OF_DNS_RESOLVER_ERROR_NO_NAME_SERVER } of_dns_resolver_error_t; -/*! +/** * @protocol OFDNSResolverQueryDelegate OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief A delegate for performed DNS queries. */ @protocol OFDNSResolverQueryDelegate -/*! +/** * @brief This method is called when a DNS resolver performed a query. * * @param resolver The acting resolver * @param query The query performed by the resolver * @param response The response from the DNS server, or nil on error @@ -89,17 +89,17 @@ didPerformQuery: (OFDNSQuery *)query response: (nullable OFDNSResponse *)response exception: (nullable id)exception; @end -/*! +/** * @protocol OFDNSResolverQueryDelegate OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief A delegate for resolved hosts. */ @protocol OFDNSResolverHostDelegate -/*! +/** * @brief This method is called when a DNS resolver resolved a host to * addresses. * * @param resolver The acting resolver * @param host The host the resolver resolved @@ -111,11 +111,11 @@ didResolveHost: (OFString *)host addresses: (nullable OFData *)addresses exception: (nullable id)exception; @end -/*! +/** * @class OFDNSResolver OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief A class for resolving DNS names. * * @note If you change any of the properties, make sure to set @@ -136,85 +136,85 @@ *_queries; OFMutableDictionary OF_GENERIC(OFTCPSocket *, OFDNSResolverContext *) *_TCPQueries; } -/*! +/** * @brief A dictionary of static hosts. * * This dictionary is checked before actually looking up a host. */ @property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC(OFString *) *) *staticHosts; -/*! +/** * @brief An array of name servers to use. * * The name servers are tried in order. */ @property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *nameServers; -/*! +/** * @brief The local domain. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *localDomain; -/*! +/** * @brief The domains to search for queries for short names. */ @property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains; -/*! +/** * @brief The timeout, in seconds, after which the next name server should be * tried. */ @property (nonatomic) of_time_interval_t timeout; -/*! +/** * @brief The number of attempts before giving up to resolve a host. * * Trying all name servers once is considered a single attempt. */ @property (nonatomic) unsigned int maxAttempts; -/*! +/** * @brief The minimum number of dots for a name to be considered absolute. */ @property (nonatomic) unsigned int minNumberOfDotsInAbsoluteName; -/*! +/** * @brief Whether the resolver uses TCP to talk to a name server. */ @property (nonatomic) bool usesTCP; -/*! +/** * @brief The interval in seconds in which the config should be reloaded. * * Setting this to 0 disables config reloading. */ @property (nonatomic) of_time_interval_t configReloadInterval; -/*! +/** * @brief Creates a new, autoreleased OFDNSResolver. */ + (instancetype)resolver; -/*! +/** * @brief Initializes an already allocated OFDNSResolver. */ - (instancetype)init; -/*! +/** * @brief Asynchronously performs the specified query. * * @param query The query to perform * @param delegate The delegate to use for callbacks */ - (void)asyncPerformQuery: (OFDNSQuery *)query delegate: (id )delegate; -/*! +/** * @brief Asynchronously performs the specified query. * * @param query The query to perform * @param runLoopMode The run loop mode in which to resolve * @param delegate The delegate to use for callbacks @@ -221,20 +221,20 @@ */ - (void)asyncPerformQuery: (OFDNSQuery *)query runLoopMode: (of_run_loop_mode_t)runLoopMode delegate: (id )delegate; -/*! +/** * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param delegate The delegate to use for callbacks */ - (void)asyncResolveAddressesForHost: (OFString *)host delegate: (id )delegate; -/*! +/** * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @param delegate The delegate to use for callbacks @@ -241,11 +241,11 @@ */ - (void)asyncResolveAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t)addressFamily delegate: (id )delegate; -/*! +/** * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @param runLoopMode The run loop mode in which to resolve @@ -254,22 +254,22 @@ - (void)asyncResolveAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t)addressFamily runLoopMode: (of_run_loop_mode_t)runLoopMode delegate: (id )delegate; -/*! +/** * @brief Synchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @return OFData containing several of_socket_address_t */ - (OFData *)resolveAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t)addressFamily; -/*! +/** * @brief Closes all sockets and cancels all ongoing queries. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -491,11 +491,11 @@ queryData = [OFMutableData dataWithCapacity: 512]; /* Header */ - tmp = OF_BSWAP16_IF_LE(_ID.uInt16Value); + tmp = OF_BSWAP16_IF_LE(_ID.unsignedShortValue); [queryData addItems: &tmp count: 2]; /* RD */ tmp = OF_BSWAP16_IF_LE(1u << 8); @@ -812,11 +812,11 @@ OFNumber *ID; OFDNSResolverContext *context; /* Random, unused ID */ do { - ID = [OFNumber numberWithUInt16: (uint16_t)of_random()]; + ID = [OFNumber numberWithUnsignedShort: of_random16()]; } while ([_queries objectForKey: ID] != nil); if (query.domainName.UTF8StringLength > 253) @throw [OFOutOfRangeException exception]; @@ -911,11 +911,11 @@ if (length < 2) /* We can't get the ID to get the context. Ignore packet. */ return true; - ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]]; + ID = [OFNumber numberWithUnsignedShort: (buffer[0] << 8) | buffer[1]]; context = [[[_queries objectForKey: ID] retain] autorelease]; if (context == nil) return true; Index: src/OFDNSResolverSettings.m ================================================================== --- src/OFDNSResolverSettings.m +++ src/OFDNSResolverSettings.m @@ -32,10 +32,11 @@ #endif #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" +#import "OFOutOfRangeException.h" #ifdef OF_WINDOWS # define interface struct # include # undef interface @@ -69,11 +70,11 @@ #ifndef OF_WII static OFString * domainFromHostname(void) { char hostname[256]; - OFString *domain; + OFString *domain, *ret; if (gethostname(hostname, 256) != 0) return nil; domain = [OFString stringWithCString: hostname @@ -92,13 +93,15 @@ size_t pos = [domain rangeOfString: @"."].location; if (pos == OF_NOT_FOUND) return nil; - return [domain substringWithRange: + ret = [domain substringWithRange: of_range(pos + 1, domain.length - pos - 1)]; } + + return ret; } #endif @implementation OFDNSResolverSettings - (void)dealloc @@ -236,30 +239,41 @@ # if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4) - (void)parseResolvConfOption: (OFString *)option { @try { if ([option hasPrefix: @"ndots:"]) { + unsigned long long number; + option = [option substringWithRange: of_range(6, option.length - 6)]; + number = option.unsignedLongLongValue; + + if (number > UINT_MAX) + @throw [OFOutOfRangeException exception]; - _minNumberOfDotsInAbsoluteName = - (unsigned int)option.decimalValue; + _minNumberOfDotsInAbsoluteName = (unsigned int)number; } else if ([option hasPrefix: @"timeout:"]) { option = [option substringWithRange: of_range(8, option.length - 8)]; - _timeout = option.decimalValue; + _timeout = option.unsignedLongLongValue; } else if ([option hasPrefix: @"attempts:"]) { + unsigned long long number; + option = [option substringWithRange: of_range(9, option.length - 9)]; + number = option.unsignedLongLongValue; + + if (number > UINT_MAX) + @throw [OFOutOfRangeException exception]; - _maxAttempts = (unsigned int)option.decimalValue; + _maxAttempts = (unsigned int)number; } else if ([option hasPrefix: @"reload-period:"]) { option = [option substringWithRange: of_range(14, option.length - 14)]; - _configReloadInterval = option.decimalValue; + _configReloadInterval = option.unsignedLongLongValue; } else if ([option isEqual: @"tcp"]) _usesTCP = true; } @catch (OFInvalidFormatException *e) { } } Index: src/OFDNSResourceRecord.h ================================================================== --- src/OFDNSResourceRecord.h +++ src/OFDNSResourceRecord.h @@ -20,56 +20,56 @@ #import "socket.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFArray OF_GENERIC(ObjectType); @class OFData; -/*! +/** * @brief The DNS class. */ typedef enum { - /*! IN */ + /** IN */ OF_DNS_CLASS_IN = 1, - /*! Any class. Only for queries. */ + /** Any class. Only for queries. */ OF_DNS_CLASS_ANY = 255, } of_dns_class_t; -/*! +/** * @brief The type of a DNS resource record. */ typedef enum { - /*! A */ + /** A */ OF_DNS_RECORD_TYPE_A = 1, - /*! NS */ + /** NS */ OF_DNS_RECORD_TYPE_NS = 2, - /*! CNAME */ + /** CNAME */ OF_DNS_RECORD_TYPE_CNAME = 5, - /*! SOA */ + /** SOA */ OF_DNS_RECORD_TYPE_SOA = 6, - /*! PTR */ + /** PTR */ OF_DNS_RECORD_TYPE_PTR = 12, - /*! HINFO */ + /** HINFO */ OF_DNS_RECORD_TYPE_HINFO = 13, - /*! MX */ + /** MX */ OF_DNS_RECORD_TYPE_MX = 15, - /*! TXT */ + /** TXT */ OF_DNS_RECORD_TYPE_TXT = 16, - /*! RP */ + /** RP */ OF_DNS_RECORD_TYPE_RP = 17, - /*! AAAA */ + /** AAAA */ OF_DNS_RECORD_TYPE_AAAA = 28, - /*! SRV */ + /** SRV */ OF_DNS_RECORD_TYPE_SRV = 33, - /*! All types. Only for queries. */ + /** All types. Only for queries. */ OF_DNS_RECORD_TYPE_ALL = 255, } of_dns_record_type_t; -/*! +/** * @class OFDNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a DNS resource record. */ @interface OFDNSResourceRecord: OFObject @@ -76,35 +76,35 @@ { OFString *_name; of_dns_class_t _DNSClass; of_dns_record_type_t _recordType; uint32_t _TTL; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFDNSResourceRecord, 4) } /** * @brief The domain name to which the resource record belongs. */ @property (readonly, nonatomic) OFString *name; -/*! +/** * @brief The DNS class. */ @property (readonly, nonatomic) of_dns_class_t DNSClass; -/*! +/** * @brief The resource record type code. */ @property (readonly, nonatomic) of_dns_record_type_t recordType; -/*! +/** * @brief The number of seconds after which the resource record should be * discarded from the cache. */ @property (readonly, nonatomic) uint32_t TTL; -/*! +/** * @brief Initializes an already allocated OFDNSResourceRecord with the * specified name, class, type, data and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -116,11 +116,11 @@ DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFADNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an A DNS resource record. */ OF_SUBCLASSING_RESTRICTED @@ -127,21 +127,21 @@ @interface OFADNSResourceRecord: OFDNSResourceRecord { of_socket_address_t _address; } -/*! +/** * @brief The IPv4 address of the resource record. */ @property (readonly, nonatomic) const of_socket_address_t *address; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFADNSResourceRecord with the * specified name, class, address and time to live. * * @param name The name for the resource record * @param address The address for the resource record @@ -151,11 +151,11 @@ - (instancetype)initWithName: (OFString *)name address: (const of_socket_address_t *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFAAAADNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class represenging a DNS resource record. */ @@ -163,21 +163,21 @@ @interface OFAAAADNSResourceRecord: OFDNSResourceRecord { of_socket_address_t _address; } -/*! +/** * @brief The IPv6 address of the resource record. */ @property (readonly, nonatomic) const of_socket_address_t *address; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFAAAADNSResourceRecord with the * specified name, class, address and time to live. * * @param name The name for the resource record * @param address The address for the resource record @@ -187,11 +187,11 @@ - (instancetype)initWithName: (OFString *)name address: (const of_socket_address_t *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFCNAMEDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a CNAME DNS resource record. */ @@ -199,21 +199,21 @@ @interface OFCNAMEDNSResourceRecord: OFDNSResourceRecord { OFString *_alias; } -/*! +/** * @brief The alias of the resource record. */ @property (readonly, nonatomic) OFString *alias; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFCNAMEDNSResourceRecord with the * specified name, class, alias and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -225,11 +225,11 @@ DNSClass: (of_dns_class_t)DNSClass alias: (OFString *)alias TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFHINFODNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an HINFO DNS resource record. */ @@ -237,26 +237,26 @@ @interface OFHINFODNSResourceRecord: OFDNSResourceRecord { OFString *_CPU, *_OS; } -/*! +/** * @brief The CPU of the host info of the resource record. */ @property (readonly, nonatomic) OFString *CPU; -/*! +/** * @brief The OS of the host info of the resource record. */ @property (readonly, nonatomic) OFString *OS; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFHINFODNSResourceRecord with the * specified name, class, domain name and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -270,11 +270,11 @@ CPU: (OFString *)CPU OS: (OFString *)OS TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFMXDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an MX DNS resource record. */ @@ -283,26 +283,26 @@ { uint16_t _preference; OFString *_mailExchange; } -/*! +/** * @brief The preference of the resource record. */ @property (readonly, nonatomic) uint16_t preference; -/*! +/** * @brief The mail exchange of the resource record. */ @property (readonly, nonatomic) OFString *mailExchange; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFMXDNSResourceRecord with the * specified name, class, preference, mail exchange and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -316,11 +316,11 @@ preference: (uint16_t)preference mailExchange: (OFString *)mailExchange TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFNSDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an NS DNS resource record. */ @@ -328,21 +328,21 @@ @interface OFNSDNSResourceRecord: OFDNSResourceRecord { OFString *_authoritativeHost; } -/*! +/** * @brief The authoritative host of the resource record. */ @property (readonly, nonatomic) OFString *authoritativeHost; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFNSDNSResourceRecord with the * specified name, class, authoritative host and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -354,11 +354,11 @@ DNSClass: (of_dns_class_t)DNSClass authoritativeHost: (OFString *)authoritativeHost TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFPTRDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a PTR DNS resource record. */ @@ -366,21 +366,21 @@ @interface OFPTRDNSResourceRecord: OFDNSResourceRecord { OFString *_domainName; } -/*! +/** * @brief The domain name of the resource record. */ @property (readonly, nonatomic) OFString *domainName; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFPTRDNSResourceRecord with the * specified name, class, domain name and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -392,11 +392,11 @@ DNSClass: (of_dns_class_t)DNSClass domainName: (OFString *)domainName TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFRPNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an RP DNS resource record. */ @@ -404,16 +404,16 @@ @interface OFRPDNSResourceRecord: OFDNSResourceRecord { OFString *_mailbox, *_TXTDomainName; } -/*! +/** * @brief The mailbox of the responsible person of the resource record. */ @property (readonly, nonatomic) OFString *mailbox; -/*! +/** * @brief A domain name that contains a TXT resource record for the responsible * person of the resource record. */ @property (readonly, nonatomic) OFString *TXTDomainName; @@ -420,11 +420,11 @@ - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFRPDNSResourceRecord with the * specified name, class, alias and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -439,11 +439,11 @@ mailbox: (OFString *)mailbox TXTDomainName: (OFString *)TXTDomainName TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFSOADNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an SOA DNS resource record. */ @@ -453,51 +453,51 @@ OFString *_primaryNameServer, *_responsiblePerson; uint32_t _serialNumber, _refreshInterval, _retryInterval; uint32_t _expirationInterval, _minTTL; } -/*! +/** * @brief The the primary name server for the zone. */ @property (readonly, nonatomic) OFString *primaryNameServer; -/*! +/** * @brief The mailbox of the person responsible for the zone. */ @property (readonly, nonatomic) OFString *responsiblePerson; -/*! +/** * @brief The serial number of the original copy of the zone. */ @property (readonly, nonatomic) uint32_t serialNumber; -/*! +/** * @brief The refresh interval of the zone. */ @property (readonly, nonatomic) uint32_t refreshInterval; -/*! +/** * @brief The retry interval of the zone. */ @property (readonly, nonatomic) uint32_t retryInterval; -/*! +/** * @brief The expiration interval of the zone. */ @property (readonly, nonatomic) uint32_t expirationInterval; -/*! +/** * @brief The minimum TTL of the zone. */ @property (readonly, nonatomic) uint32_t minTTL; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFSOADNSResourceRecord with the * specified name, class, text data and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record @@ -521,11 +521,11 @@ expirationInterval: (uint32_t)expirationInterval minTTL: (uint32_t)minTTL TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFSRVDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an SRV DNS resource record. */ @@ -535,36 +535,36 @@ uint16_t _priority, _weight; OFString *_target; uint16_t _port; } -/*! +/** * @brief The priority of the resource record. */ @property (readonly, nonatomic) uint16_t priority; -/*! +/** * @brief The weight of the resource record. */ @property (readonly, nonatomic) uint16_t weight; -/*! +/** * @brief The target of the resource record. */ @property (readonly, nonatomic) OFString *target; -/*! +/** * @brief The port on the target of the resource record. */ @property (readonly, nonatomic) uint16_t port; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFSRVDNSResourceRecord with the * specified name, class, preference, mail exchange and time to live. * * @param name The name for the resource record * @param priority The priority for the resource record @@ -580,11 +580,11 @@ target: (OFString *)target port: (uint16_t)port TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end -/*! +/** * @class OFTXTDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a TXT DNS resource record. */ @@ -592,21 +592,21 @@ @interface OFTXTDNSResourceRecord: OFDNSResourceRecord { OFArray OF_GENERIC(OFData *) *_textStrings; } -/*! +/** * @brief The text of the resource record. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFData *) *textStrings; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFTXTDNSResourceRecord with the * specified name, class, text data and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record Index: src/OFDNSResourceRecord.m ================================================================== --- src/OFDNSResourceRecord.m +++ src/OFDNSResourceRecord.m @@ -79,11 +79,12 @@ if ([string isEqual: @"IN"]) DNSClass = OF_DNS_CLASS_IN; else { @try { - DNSClass = (of_dns_class_t)string.decimalValue; + DNSClass = (of_dns_class_t) + [string unsignedLongLongValueWithBase: 0]; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidArgumentException exception]; } } @@ -123,12 +124,12 @@ recordType = OF_DNS_RECORD_TYPE_SRV; else if ([string isEqual: @"ALL"]) recordType = OF_DNS_RECORD_TYPE_ALL; else { @try { - recordType = - (of_dns_record_type_t)string.decimalValue; + recordType = (of_dns_record_type_t) + [string unsignedLongLongValueWithBase: 0]; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidArgumentException exception]; } } Index: src/OFDNSResponse.h ================================================================== --- src/OFDNSResponse.h +++ src/OFDNSResponse.h @@ -24,11 +24,11 @@ @class OFDictionary OF_GENERIC(KeyType, ObjectType); typedef OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC( OF_KINDOF(OFDNSResourceRecord *)) *) *of_dns_response_records_t; -/*! +/** * @class OFDNSResponse OFDNSResponse.h ObjFW/OFDNSResponse.h * * @brief A class storing a response from @ref OFDNSResolver. */ @interface OFDNSResponse: OFObject @@ -35,43 +35,43 @@ { OFString *_domainName; of_dns_response_records_t _answerRecords; of_dns_response_records_t _authorityRecords; of_dns_response_records_t _additionalRecords; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFDNSResponse, 4) } -/*! +/** * @brief The domain name of the response. */ @property (readonly, nonatomic) OFString *domainName; -/*! +/** * @brief The answer records of the response. * * This is a dictionary with the key being the domain name and the value being * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) of_dns_response_records_t answerRecords; -/*! +/** * @brief The authority records of the response. * * This is a dictionary with the key being the domain name and the value being * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) of_dns_response_records_t authorityRecords; -/*! +/** * @brief The additional records of the response. * * This is a dictionary with the key being the domain name and the value being * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) of_dns_response_records_t additionalRecords; -/*! +/** * @brief Creates a new, autoreleased OFDNSResponse. * * @param domainName The domain name the response is for * @param answerRecords The answer records of the response * @param authorityRecords The authority records of the response @@ -82,11 +82,11 @@ responseWithDomainName: (OFString *)domainName answerRecords: (of_dns_response_records_t)answerRecords authorityRecords: (of_dns_response_records_t)authorityRecords additionalRecords: (of_dns_response_records_t)additionalRecords; -/*! +/** * @brief Initializes an already allocated OFDNSResponse. * * @param domainName The domain name the response is for * @param answerRecords The answer records of the response * @param authorityRecords The authority records of the response ADDED src/OFData+ASN1DERParsing.h Index: src/OFData+ASN1DERParsing.h ================================================================== --- src/OFData+ASN1DERParsing.h +++ src/OFData+ASN1DERParsing.h @@ -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. + */ + +#import "OFData.h" +#import "OFASN1Value.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFData_ASN1DERParsing_reference; +#ifdef __cplusplus +} +#endif + +@interface OFData (ASN1DERParsing) +/** + * @brief The data interpreted as ASN.1 in DER representation and parsed as an + * object. + * + * This is either an OFArray (for a sequence), an OFSet (for a set) or an + * OFASN1Value. + */ +@property (readonly, nonatomic) id objectByParsingASN1DER; + +/** + * @brief Parses the ASN.1 DER representation and returns it as an object. + * + * This is either an OFArray (for a sequence), an OFSet (for a set) or an + * OFASN1Value. + * + * @param depthLimit The maximum depth the parser should accept (defaults to 32 + * if not specified, 0 means no limit (insecure!)) + * @return The ASN.1 DER representation as an object + */ +- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFData+ASN1DERParsing.m Index: src/OFData+ASN1DERParsing.m ================================================================== --- src/OFData+ASN1DERParsing.m +++ src/OFData+ASN1DERParsing.m @@ -0,0 +1,251 @@ +/* + * 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 "OFData+ASN1DERParsing.h" +#import "OFASN1BitString.h" +#import "OFASN1Boolean.h" +#import "OFASN1Enumerated.h" +#import "OFASN1IA5String.h" +#import "OFASN1Integer.h" +#import "OFASN1NumericString.h" +#import "OFASN1ObjectIdentifier.h" +#import "OFASN1OctetString.h" +#import "OFASN1PrintableString.h" +#import "OFASN1UTF8String.h" +#import "OFASN1Value.h" +#import "OFArray.h" +#import "OFNull.h" +#import "OFSet.h" + +#import "OFInvalidArgumentException.h" +#import "OFInvalidFormatException.h" +#import "OFOutOfRangeException.h" +#import "OFTruncatedDataException.h" + +enum { + ASN1_TAG_CONSTRUCTED_MASK = 0x20 +}; + +int _OFData_ASN1DERParsing_reference; + +static size_t parseObject(OFData *self, id *object, size_t depthLimit); + +static OFArray * +parseSequence(OFData *contents, size_t depthLimit) +{ + OFMutableArray *ret = [OFMutableArray array]; + size_t count = contents.count; + + if (depthLimit == 0) + @throw [OFOutOfRangeException exception]; + + while (count > 0) { + id object; + size_t objectLength; + + objectLength = parseObject(contents, &object, depthLimit); + + count -= objectLength; + contents = [contents subdataWithRange: + of_range(objectLength, count)]; + + [ret addObject: object]; + } + + [ret makeImmutable]; + + return ret; +} + +static OFSet * +parseSet(OFData *contents, size_t depthLimit) +{ + OFMutableSet *ret = [OFMutableSet set]; + size_t count = contents.count; + OFData *previousObjectData = nil; + + if (depthLimit == 0) + @throw [OFOutOfRangeException exception]; + + while (count > 0) { + id object; + size_t objectLength; + OFData *objectData; + + objectLength = parseObject(contents, &object, depthLimit); + objectData = [contents subdataWithRange: + of_range(0, objectLength)]; + + if (previousObjectData != nil && + [objectData compare: previousObjectData] != + OF_ORDERED_DESCENDING) + @throw [OFInvalidFormatException exception]; + + count -= objectLength; + contents = [contents subdataWithRange: + of_range(objectLength, count)]; + + [ret addObject: object]; + + previousObjectData = objectData; + } + + [ret makeImmutable]; + + return ret; +} + +static size_t +parseObject(OFData *self, id *object, size_t depthLimit) +{ + const unsigned char *items = self.items; + size_t count = self.count; + unsigned char tag; + size_t contentsLength, bytesConsumed = 0; + Class valueClass; + OFData *contents; + + if (count < 2) + @throw [OFTruncatedDataException exception]; + + tag = *items++; + contentsLength = *items++; + bytesConsumed += 2; + + if (contentsLength > 127) { + uint_fast8_t lengthLength = contentsLength & 0x7F; + + if (lengthLength > sizeof(size_t)) + @throw [OFOutOfRangeException exception]; + + if (count - bytesConsumed < lengthLength) + @throw [OFTruncatedDataException exception]; + + if (lengthLength == 0 || + (lengthLength == 1 && items[0] < 0x80) || + (lengthLength >= 2 && items[0] == 0)) + @throw [OFInvalidFormatException exception]; + + contentsLength = 0; + + for (uint_fast8_t i = 0; i < lengthLength; i++) + contentsLength = (contentsLength << 8) | *items++; + + bytesConsumed += lengthLength; + + if (contentsLength <= 127) + @throw [OFInvalidFormatException exception]; + } + + if (count - bytesConsumed < contentsLength) + @throw [OFTruncatedDataException exception]; + + contents = [self subdataWithRange: + of_range(bytesConsumed, contentsLength)]; + bytesConsumed += contentsLength; + + switch (tag & ~ASN1_TAG_CONSTRUCTED_MASK) { + case OF_ASN1_TAG_NUMBER_BOOLEAN: + valueClass = [OFASN1Boolean class]; + break; + case OF_ASN1_TAG_NUMBER_INTEGER: + valueClass = [OFASN1Integer class]; + break; + case OF_ASN1_TAG_NUMBER_BIT_STRING: + valueClass = [OFASN1BitString class]; + break; + case OF_ASN1_TAG_NUMBER_OCTET_STRING: + valueClass = [OFASN1OctetString class]; + break; + case OF_ASN1_TAG_NUMBER_NULL: + if (tag & ASN1_TAG_CONSTRUCTED_MASK) + @throw [OFInvalidFormatException exception]; + + if (contents.count != 0) + @throw [OFInvalidFormatException exception]; + + *object = [OFNull null]; + return bytesConsumed; + case OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER: + valueClass = [OFASN1ObjectIdentifier class]; + break; + case OF_ASN1_TAG_NUMBER_ENUMERATED: + valueClass = [OFASN1Enumerated class]; + break; + case OF_ASN1_TAG_NUMBER_UTF8_STRING: + valueClass = [OFASN1UTF8String class]; + break; + case OF_ASN1_TAG_NUMBER_SEQUENCE: + if (!(tag & ASN1_TAG_CONSTRUCTED_MASK)) + @throw [OFInvalidFormatException exception]; + + *object = parseSequence(contents, depthLimit - 1); + return bytesConsumed; + case OF_ASN1_TAG_NUMBER_SET: + if (!(tag & ASN1_TAG_CONSTRUCTED_MASK)) + @throw [OFInvalidFormatException exception]; + + *object = parseSet(contents, depthLimit - 1); + return bytesConsumed; + case OF_ASN1_TAG_NUMBER_NUMERIC_STRING: + valueClass = [OFASN1NumericString class]; + break; + case OF_ASN1_TAG_NUMBER_PRINTABLE_STRING: + valueClass = [OFASN1PrintableString class]; + break; + case OF_ASN1_TAG_NUMBER_IA5_STRING: + valueClass = [OFASN1IA5String class]; + break; + default: + valueClass = [OFASN1Value class]; + break; + } + + *object = [[[valueClass alloc] + initWithTagClass: tag >> 6 + tagNumber: tag & 0x1F + constructed: tag & ASN1_TAG_CONSTRUCTED_MASK + DEREncodedContents: contents] autorelease]; + return bytesConsumed; +} + +@implementation OFData (ASN1DERParsing) +- (id)objectByParsingASN1DER +{ + return [self objectByParsingASN1DERWithDepthLimit: 32]; +} + +- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit +{ + void *pool = objc_autoreleasePoolPush(); + id object; + + if (self.itemSize != 1) + @throw [OFInvalidArgumentException exception]; + + if (parseObject(self, &object, depthLimit) != self.count) + @throw [OFInvalidFormatException exception]; + + [object retain]; + + objc_autoreleasePoolPop(pool); + + return [object autorelease]; +} +@end DELETED src/OFData+ASN1DERValue.h Index: src/OFData+ASN1DERValue.h ================================================================== --- src/OFData+ASN1DERValue.h +++ src/OFData+ASN1DERValue.h @@ -1,54 +0,0 @@ -/* - * 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. - */ - -#import "OFData.h" -#import "OFASN1Value.h" - -OF_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFData_ASN1DERValue_reference; -#ifdef __cplusplus -} -#endif - -@interface OFData (ASN1DERValue) -/*! - * @brief The data interpreted as ASN.1 in DER representation and parsed as an - * object. - * - * This is either an OFArray (for a sequence), an OFSet (for a set) or an - * OFASN1Value. - */ -@property (readonly, nonatomic) id ASN1DERValue; - -/*! - * @brief Parses the ASN.1 DER representation and returns it as an object. - * - * This is either an OFArray (for a sequence), an OFSet (for a set) or an - * OFASN1Value. - * - * @param depthLimit The maximum depth the parser should accept (defaults to 32 - * if not specified, 0 means no limit (insecure!)) - * @return The ASN.1 DER representation as an object - */ -- (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFData+ASN1DERValue.m Index: src/OFData+ASN1DERValue.m ================================================================== --- src/OFData+ASN1DERValue.m +++ src/OFData+ASN1DERValue.m @@ -1,251 +0,0 @@ -/* - * 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 "OFData+ASN1DERValue.h" -#import "OFASN1BitString.h" -#import "OFASN1Boolean.h" -#import "OFASN1Enumerated.h" -#import "OFASN1IA5String.h" -#import "OFASN1Integer.h" -#import "OFASN1NumericString.h" -#import "OFASN1ObjectIdentifier.h" -#import "OFASN1OctetString.h" -#import "OFASN1PrintableString.h" -#import "OFASN1UTF8String.h" -#import "OFASN1Value.h" -#import "OFArray.h" -#import "OFNull.h" -#import "OFSet.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFOutOfRangeException.h" -#import "OFTruncatedDataException.h" - -enum { - ASN1_TAG_CONSTRUCTED_MASK = 0x20 -}; - -int _OFData_ASN1DERValue_reference; - -static size_t parseObject(OFData *self, id *object, size_t depthLimit); - -static OFArray * -parseSequence(OFData *contents, size_t depthLimit) -{ - OFMutableArray *ret = [OFMutableArray array]; - size_t count = contents.count; - - if (depthLimit == 0) - @throw [OFOutOfRangeException exception]; - - while (count > 0) { - id object; - size_t objectLength; - - objectLength = parseObject(contents, &object, depthLimit); - - count -= objectLength; - contents = [contents subdataWithRange: - of_range(objectLength, count)]; - - [ret addObject: object]; - } - - [ret makeImmutable]; - - return ret; -} - -static OFSet * -parseSet(OFData *contents, size_t depthLimit) -{ - OFMutableSet *ret = [OFMutableSet set]; - size_t count = contents.count; - OFData *previousObjectData = nil; - - if (depthLimit == 0) - @throw [OFOutOfRangeException exception]; - - while (count > 0) { - id object; - size_t objectLength; - OFData *objectData; - - objectLength = parseObject(contents, &object, depthLimit); - objectData = [contents subdataWithRange: - of_range(0, objectLength)]; - - if (previousObjectData != nil && - [objectData compare: previousObjectData] != - OF_ORDERED_DESCENDING) - @throw [OFInvalidFormatException exception]; - - count -= objectLength; - contents = [contents subdataWithRange: - of_range(objectLength, count)]; - - [ret addObject: object]; - - previousObjectData = objectData; - } - - [ret makeImmutable]; - - return ret; -} - -static size_t -parseObject(OFData *self, id *object, size_t depthLimit) -{ - const unsigned char *items = self.items; - size_t count = self.count; - unsigned char tag; - size_t contentsLength, bytesConsumed = 0; - Class valueClass; - OFData *contents; - - if (count < 2) - @throw [OFTruncatedDataException exception]; - - tag = *items++; - contentsLength = *items++; - bytesConsumed += 2; - - if (contentsLength > 127) { - uint_fast8_t lengthLength = contentsLength & 0x7F; - - if (lengthLength > sizeof(size_t)) - @throw [OFOutOfRangeException exception]; - - if (count - bytesConsumed < lengthLength) - @throw [OFTruncatedDataException exception]; - - if (lengthLength == 0 || - (lengthLength == 1 && items[0] < 0x80) || - (lengthLength >= 2 && items[0] == 0)) - @throw [OFInvalidFormatException exception]; - - contentsLength = 0; - - for (uint_fast8_t i = 0; i < lengthLength; i++) - contentsLength = (contentsLength << 8) | *items++; - - bytesConsumed += lengthLength; - - if (contentsLength <= 127) - @throw [OFInvalidFormatException exception]; - } - - if (count - bytesConsumed < contentsLength) - @throw [OFTruncatedDataException exception]; - - contents = [self subdataWithRange: - of_range(bytesConsumed, contentsLength)]; - bytesConsumed += contentsLength; - - switch (tag & ~ASN1_TAG_CONSTRUCTED_MASK) { - case OF_ASN1_TAG_NUMBER_BOOLEAN: - valueClass = [OFASN1Boolean class]; - break; - case OF_ASN1_TAG_NUMBER_INTEGER: - valueClass = [OFASN1Integer class]; - break; - case OF_ASN1_TAG_NUMBER_BIT_STRING: - valueClass = [OFASN1BitString class]; - break; - case OF_ASN1_TAG_NUMBER_OCTET_STRING: - valueClass = [OFASN1OctetString class]; - break; - case OF_ASN1_TAG_NUMBER_NULL: - if (tag & ASN1_TAG_CONSTRUCTED_MASK) - @throw [OFInvalidFormatException exception]; - - if (contents.count != 0) - @throw [OFInvalidFormatException exception]; - - *object = [OFNull null]; - return bytesConsumed; - case OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER: - valueClass = [OFASN1ObjectIdentifier class]; - break; - case OF_ASN1_TAG_NUMBER_ENUMERATED: - valueClass = [OFASN1Enumerated class]; - break; - case OF_ASN1_TAG_NUMBER_UTF8_STRING: - valueClass = [OFASN1UTF8String class]; - break; - case OF_ASN1_TAG_NUMBER_SEQUENCE: - if (!(tag & ASN1_TAG_CONSTRUCTED_MASK)) - @throw [OFInvalidFormatException exception]; - - *object = parseSequence(contents, depthLimit - 1); - return bytesConsumed; - case OF_ASN1_TAG_NUMBER_SET: - if (!(tag & ASN1_TAG_CONSTRUCTED_MASK)) - @throw [OFInvalidFormatException exception]; - - *object = parseSet(contents, depthLimit - 1); - return bytesConsumed; - case OF_ASN1_TAG_NUMBER_NUMERIC_STRING: - valueClass = [OFASN1NumericString class]; - break; - case OF_ASN1_TAG_NUMBER_PRINTABLE_STRING: - valueClass = [OFASN1PrintableString class]; - break; - case OF_ASN1_TAG_NUMBER_IA5_STRING: - valueClass = [OFASN1IA5String class]; - break; - default: - valueClass = [OFASN1Value class]; - break; - } - - *object = [[[valueClass alloc] - initWithTagClass: tag >> 6 - tagNumber: tag & 0x1F - constructed: tag & ASN1_TAG_CONSTRUCTED_MASK - DEREncodedContents: contents] autorelease]; - return bytesConsumed; -} - -@implementation OFData (ASN1DERValue) -- (id)ASN1DERValue -{ - return [self ASN1DERValueWithDepthLimit: 32]; -} - -- (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit -{ - void *pool = objc_autoreleasePoolPush(); - id object; - - if (self.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - if (parseObject(self, &object, depthLimit) != self.count) - @throw [OFInvalidFormatException exception]; - - [object retain]; - - objc_autoreleasePoolPop(pool); - - return [object autorelease]; -} -@end Index: src/OFData+CryptoHashing.h ================================================================== --- src/OFData+CryptoHashing.h +++ src/OFData+CryptoHashing.h @@ -28,42 +28,42 @@ #ifdef __cplusplus } #endif @interface OFData (CryptoHashing) -/*! +/** * @brief The MD5 hash of the data as a string. */ @property (readonly, nonatomic) OFString *MD5Hash; -/*! +/** * @brief The RIPEMD-160 hash of the data as a string. */ @property (readonly, nonatomic) OFString *RIPEMD160Hash; -/*! +/** * @brief The SHA-1 hash of the data as a string. */ @property (readonly, nonatomic) OFString *SHA1Hash; -/*! +/** * @brief The SHA-224 hash of the data as a string. */ @property (readonly, nonatomic) OFString *SHA224Hash; -/*! +/** * @brief The SHA-256 hash of the data as a string. */ @property (readonly, nonatomic) OFString *SHA256Hash; -/*! +/** * @brief The SHA-384 hash of the data as a string. */ @property (readonly, nonatomic) OFString *SHA384Hash; -/*! +/** * @brief The SHA-512 hash of the data as a string. */ @property (readonly, nonatomic) OFString *SHA512Hash; @end OF_ASSUME_NONNULL_END ADDED src/OFData+MessagePackParsing.h Index: src/OFData+MessagePackParsing.h ================================================================== --- src/OFData+MessagePackParsing.h +++ src/OFData+MessagePackParsing.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#import "OFData.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFData_MessagePackParsing_reference; +#ifdef __cplusplus +} +#endif + +@interface OFData (MessagePackParsing) +/** + * @brief The data interpreted as MessagePack representation and parsed as an + * object. + */ +@property (readonly, nonatomic) id objectByParsingMessagePack; + +/** + * @brief Parses the MessagePack representation and returns it as an object. + * + * @param depthLimit The maximum depth the parser should accept (defaults to 32 + * if not specified, 0 means no limit (insecure!)) + * @return The MessagePack representation as an object + */ +- (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFData+MessagePackParsing.m Index: src/OFData+MessagePackParsing.m ================================================================== --- src/OFData+MessagePackParsing.m +++ src/OFData+MessagePackParsing.m @@ -0,0 +1,572 @@ +/* + * 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" + +#include + +#import "OFData+MessagePackParsing.h" +#import "OFArray.h" +#import "OFDate.h" +#import "OFDictionary.h" +#import "OFMessagePackExtension.h" +#import "OFNull.h" +#import "OFNumber.h" +#import "OFString.h" + +#import "OFInvalidArgumentException.h" +#import "OFInvalidFormatException.h" +#import "OFOutOfRangeException.h" +#import "OFTruncatedDataException.h" + +int _OFData_MessagePackParsing_reference; + +static size_t parseObject(const unsigned char *buffer, size_t length, + id *object, size_t depthLimit); + +static uint16_t +readUInt16(const unsigned char *buffer) +{ + return ((uint16_t)buffer[0] << 8) | buffer[1]; +} + +static uint32_t +readUInt32(const unsigned char *buffer) +{ + return ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | + ((uint32_t)buffer[2] << 8) | buffer[3]; +} + +static uint64_t +readUInt64(const unsigned char *buffer) +{ + return ((uint64_t)buffer[0] << 56) | ((uint64_t)buffer[1] << 48) | + ((uint64_t)buffer[2] << 40) | ((uint64_t)buffer[3] << 32) | + ((uint64_t)buffer[4] << 24) | ((uint64_t)buffer[5] << 16) | + ((uint64_t)buffer[6] << 8) | buffer[7]; +} + +static size_t +parseArray(const unsigned char *buffer, size_t length, id *object, size_t count, + size_t depthLimit) +{ + void *pool; + size_t pos = 0; + + if (--depthLimit == 0) + @throw [OFOutOfRangeException exception]; + + /* + * Don't use capacity! For data and strings, this is safe, as we can + * check if we still have enough bytes left. For an array however, we + * can't know this, as every child can be more than one byte. + */ + *object = [OFMutableArray array]; + + for (size_t i = 0; i < count; i++) { + id child; + + pool = objc_autoreleasePoolPush(); + + pos += parseObject(buffer + pos, length - pos, &child, + depthLimit); + + [*object addObject: child]; + + objc_autoreleasePoolPop(pool); + } + + return pos; +} + +static size_t +parseTable(const unsigned char *buffer, size_t length, id *object, size_t count, + size_t depthLimit) +{ + void *pool; + size_t pos = 0; + + if (--depthLimit == 0) + @throw [OFOutOfRangeException exception]; + + /* + * Don't use capacity! For data and strings, this is safe, as we can + * check if we still have enough bytes left. For a dictionary however, + * we can't know this, as every key / value can be more than one byte. + */ + *object = [OFMutableDictionary dictionary]; + + for (size_t i = 0; i < count; i++) { + id key, value; + + pool = objc_autoreleasePoolPush(); + + pos += parseObject(buffer + pos, length - pos, &key, + depthLimit); + pos += parseObject(buffer + pos, length - pos, &value, + depthLimit); + + [*object setObject: value + forKey: key]; + + objc_autoreleasePoolPop(pool); + } + + return pos; +} + +static OFDate * +createDate(OFData *data) +{ + switch (data.count) { + case 4: { + uint32_t timestamp; + + memcpy(×tamp, data.items, 4); + timestamp = OF_BSWAP32_IF_LE(timestamp); + + return [OFDate dateWithTimeIntervalSince1970: timestamp]; + } + case 8: { + uint64_t combined; + + memcpy(&combined, data.items, 8); + combined = OF_BSWAP64_IF_LE(combined); + + return [OFDate dateWithTimeIntervalSince1970: + (double)(combined & 0x3FFFFFFFF) + + (double)(combined >> 34) / 1000000000]; + } + case 12: { + uint32_t nanoseconds; + int64_t seconds; + + memcpy(&nanoseconds, data.items, 4); + memcpy(&seconds, (char *)data.items + 4, 8); + + nanoseconds = OF_BSWAP32_IF_LE(nanoseconds); + seconds = OF_BSWAP64_IF_LE(seconds); + + return [OFDate dateWithTimeIntervalSince1970: + (double)seconds + (double)nanoseconds / 1000000000]; + } + default: + @throw [OFInvalidFormatException exception]; + } +} + +static id +createExtension(int8_t type, OFData *data) +{ + switch (type) { + case -1: + return createDate(data); + default: + return [OFMessagePackExtension extensionWithType: type + data: data]; + } +} + +static size_t +parseObject(const unsigned char *buffer, size_t length, id *object, + size_t depthLimit) +{ + size_t count; + OFData *data; + + if (length < 1) + @throw [OFTruncatedDataException exception]; + + /* positive fixint */ + if ((buffer[0] & 0x80) == 0) { + *object = [OFNumber numberWithUnsignedChar: buffer[0] & 0x7F]; + return 1; + } + /* negative fixint */ + if ((buffer[0] & 0xE0) == 0xE0) { + *object = [OFNumber numberWithChar: + ((int8_t)(buffer[0] & 0x1F)) - 32]; + return 1; + } + + /* fixstr */ + if ((buffer[0] & 0xE0) == 0xA0) { + count = buffer[0] & 0x1F; + + if (length < count + 1) + @throw [OFTruncatedDataException exception]; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 1 + length: count]; + return count + 1; + } + + /* fixarray */ + if ((buffer[0] & 0xF0) == 0x90) + return parseArray(buffer + 1, length - 1, object, + buffer[0] & 0xF, depthLimit) + 1; + + /* fixmap */ + if ((buffer[0] & 0xF0) == 0x80) + return parseTable(buffer + 1, length - 1, object, + buffer[0] & 0xF, depthLimit) + 1; + + /* Prefix byte */ + switch (buffer[0]) { + /* Unsigned integers */ + case 0xCC: /* uint8 */ + if (length < 2) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithUnsignedChar: buffer[1]]; + return 2; + case 0xCD: /* uint 16 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithUnsignedShort: + readUInt16(buffer + 1)]; + return 3; + case 0xCE: /* uint 32 */ + if (length < 5) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithUnsignedLong: + readUInt32(buffer + 1)]; + return 5; + case 0xCF: /* uint 64 */ + if (length < 9) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithUnsignedLongLong: + readUInt64(buffer + 1)]; + return 9; + /* Signed integers */ + case 0xD0: /* int 8 */ + if (length < 2) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithChar: buffer[1]]; + return 2; + case 0xD1: /* int 16 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithShort: readUInt16(buffer + 1)]; + return 3; + case 0xD2: /* int 32 */ + if (length < 5) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithLong: readUInt32(buffer + 1)]; + return 5; + case 0xD3: /* int 64 */ + if (length < 9) + @throw [OFTruncatedDataException exception]; + + *object = [OFNumber numberWithLongLong: readUInt64(buffer + 1)]; + return 9; + /* Floating point */ + case 0xCA:; /* float 32 */ + float f; + + if (length < 5) + @throw [OFTruncatedDataException exception]; + + memcpy(&f, buffer + 1, 4); + + *object = [OFNumber numberWithFloat: OF_BSWAP_FLOAT_IF_LE(f)]; + return 5; + case 0xCB:; /* float 64 */ + double d; + + if (length < 9) + @throw [OFTruncatedDataException exception]; + + memcpy(&d, buffer + 1, 8); + + *object = [OFNumber numberWithDouble: OF_BSWAP_DOUBLE_IF_LE(d)]; + return 9; + /* nil */ + case 0xC0: + *object = [OFNull null]; + return 1; + /* false */ + case 0xC2: + *object = [OFNumber numberWithBool: false]; + return 1; + /* true */ + case 0xC3: + *object = [OFNumber numberWithBool: true]; + return 1; + /* Data */ + case 0xC4: /* bin 8 */ + if (length < 2) + @throw [OFTruncatedDataException exception]; + + count = buffer[1]; + + if (length < count + 2) + @throw [OFTruncatedDataException exception]; + + *object = [OFData dataWithItems: buffer + 2 + count: count]; + + return count + 2; + case 0xC5: /* bin 16 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + count = readUInt16(buffer + 1); + + if (length < count + 3) + @throw [OFTruncatedDataException exception]; + + *object = [OFData dataWithItems: buffer + 3 + count: count]; + + return count + 3; + case 0xC6: /* bin 32 */ + if (length < 5) + @throw [OFTruncatedDataException exception]; + + count = readUInt32(buffer + 1); + + if (length < count + 5) + @throw [OFTruncatedDataException exception]; + + *object = [OFData dataWithItems: buffer + 5 + count: count]; + + return count + 5; + /* Extensions */ + case 0xC7: /* ext 8 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + count = buffer[1]; + + if (length < count + 3) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 3 + count: count]; + @try { + *object = createExtension(buffer[2], data); + } @finally { + [data release]; + } + + return count + 3; + case 0xC8: /* ext 16 */ + if (length < 4) + @throw [OFTruncatedDataException exception]; + + count = readUInt16(buffer + 1); + + if (length < count + 4) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 4 + count: count]; + @try { + *object = createExtension(buffer[3], data); + } @finally { + [data release]; + } + + return count + 4; + case 0xC9: /* ext 32 */ + if (length < 6) + @throw [OFTruncatedDataException exception]; + + count = readUInt32(buffer + 1); + + if (length < count + 6) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 6 + count: count]; + @try { + *object = createExtension(buffer[5], data); + } @finally { + [data release]; + } + + return count + 6; + case 0xD4: /* fixext 1 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 1]; + @try { + *object = createExtension(buffer[1], data); + } @finally { + [data release]; + } + + return 3; + case 0xD5: /* fixext 2 */ + if (length < 4) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 2]; + @try { + *object = createExtension(buffer[1], data); + } @finally { + [data release]; + } + + return 4; + case 0xD6: /* fixext 4 */ + if (length < 6) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 4]; + @try { + *object = createExtension(buffer[1], data); + } @finally { + [data release]; + } + + return 6; + case 0xD7: /* fixext 8 */ + if (length < 10) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 8]; + @try { + *object = createExtension(buffer[1], data); + } @finally { + [data release]; + } + + return 10; + case 0xD8: /* fixext 16 */ + if (length < 18) + @throw [OFTruncatedDataException exception]; + + data = [[OFData alloc] initWithItems: buffer + 2 + count: 16]; + @try { + *object = createExtension(buffer[1], data); + } @finally { + [data release]; + } + + return 18; + /* Strings */ + case 0xD9: /* str 8 */ + if (length < 2) + @throw [OFTruncatedDataException exception]; + + count = buffer[1]; + + if (length < count + 2) + @throw [OFTruncatedDataException exception]; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 2 + length: count]; + return count + 2; + case 0xDA: /* str 16 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + count = readUInt16(buffer + 1); + + if (length < count + 3) + @throw [OFTruncatedDataException exception]; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 3 + length: count]; + return count + 3; + case 0xDB: /* str 32 */ + if (length < 5) + @throw [OFTruncatedDataException exception]; + + count = readUInt32(buffer + 1); + + if (length < count + 5) + @throw [OFTruncatedDataException exception]; + + *object = [OFString + stringWithUTF8String: (const char *)buffer + 5 + length: count]; + return count + 5; + /* Arrays */ + case 0xDC: /* array 16 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + return parseArray(buffer + 3, length - 3, object, + readUInt16(buffer + 1), depthLimit) + 3; + case 0xDD: /* array 32 */ + if (length < 5) + @throw [OFTruncatedDataException exception]; + + return parseArray(buffer + 5, length - 5, object, + readUInt32(buffer + 1), depthLimit) + 5; + /* Maps */ + case 0xDE: /* map 16 */ + if (length < 3) + @throw [OFTruncatedDataException exception]; + + return parseTable(buffer + 3, length - 3, object, + readUInt16(buffer + 1), depthLimit) + 3; + case 0xDF: /* map 32 */ + if (length < 5) + @throw [OFTruncatedDataException exception]; + + return parseTable(buffer + 5, length - 5, object, + readUInt32(buffer + 1), depthLimit) + 5; + default: + @throw [OFInvalidFormatException exception]; + } +} + +@implementation OFData (MessagePackParsing) +- (id)objectByParsingMessagePack +{ + return [self objectByParsingMessagePackWithDepthLimit: 32]; +} + +- (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit +{ + void *pool = objc_autoreleasePoolPush(); + size_t count = self.count; + id object; + + if (self.itemSize != 1) + @throw [OFInvalidArgumentException exception]; + + if (parseObject(self.items, count, &object, depthLimit) != count) + @throw [OFInvalidFormatException exception]; + + [object retain]; + + objc_autoreleasePoolPop(pool); + + return [object autorelease]; +} +@end DELETED src/OFData+MessagePackValue.h Index: src/OFData+MessagePackValue.h ================================================================== --- src/OFData+MessagePackValue.h +++ src/OFData+MessagePackValue.h @@ -1,47 +0,0 @@ -/* - * 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. - */ - -#import "OFData.h" - -OF_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFData_MessagePackValue_reference; -#ifdef __cplusplus -} -#endif - -@interface OFData (MessagePackValue) -/*! - * @brief The data interpreted as MessagePack representation and parsed as an - * object. - */ -@property (readonly, nonatomic) id messagePackValue; - -/*! - * @brief Parses the MessagePack representation and returns it as an object. - * - * @param depthLimit The maximum depth the parser should accept (defaults to 32 - * if not specified, 0 means no limit (insecure!)) - * @return The MessagePack representation as an object - */ -- (id)messagePackValueWithDepthLimit: (size_t)depthLimit; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFData+MessagePackValue.m Index: src/OFData+MessagePackValue.m ================================================================== --- src/OFData+MessagePackValue.m +++ src/OFData+MessagePackValue.m @@ -1,569 +0,0 @@ -/* - * 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" - -#include - -#import "OFData+MessagePackValue.h" -#import "OFArray.h" -#import "OFDate.h" -#import "OFDictionary.h" -#import "OFMessagePackExtension.h" -#import "OFNull.h" -#import "OFNumber.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFOutOfRangeException.h" -#import "OFTruncatedDataException.h" - -int _OFData_MessagePackValue_reference; - -static size_t parseObject(const unsigned char *buffer, size_t length, - id *object, size_t depthLimit); - -static uint16_t -readUInt16(const unsigned char *buffer) -{ - return ((uint16_t)buffer[0] << 8) | buffer[1]; -} - -static uint32_t -readUInt32(const unsigned char *buffer) -{ - return ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | - ((uint32_t)buffer[2] << 8) | buffer[3]; -} - -static uint64_t -readUInt64(const unsigned char *buffer) -{ - return ((uint64_t)buffer[0] << 56) | ((uint64_t)buffer[1] << 48) | - ((uint64_t)buffer[2] << 40) | ((uint64_t)buffer[3] << 32) | - ((uint64_t)buffer[4] << 24) | ((uint64_t)buffer[5] << 16) | - ((uint64_t)buffer[6] << 8) | buffer[7]; -} - -static size_t -parseArray(const unsigned char *buffer, size_t length, id *object, size_t count, - size_t depthLimit) -{ - void *pool; - size_t pos = 0; - - if (--depthLimit == 0) - @throw [OFOutOfRangeException exception]; - - /* - * Don't use capacity! For data and strings, this is safe, as we can - * check if we still have enough bytes left. For an array however, we - * can't know this, as every child can be more than one byte. - */ - *object = [OFMutableArray array]; - - for (size_t i = 0; i < count; i++) { - id child; - - pool = objc_autoreleasePoolPush(); - - pos += parseObject(buffer + pos, length - pos, &child, - depthLimit); - - [*object addObject: child]; - - objc_autoreleasePoolPop(pool); - } - - return pos; -} - -static size_t -parseTable(const unsigned char *buffer, size_t length, id *object, size_t count, - size_t depthLimit) -{ - void *pool; - size_t pos = 0; - - if (--depthLimit == 0) - @throw [OFOutOfRangeException exception]; - - /* - * Don't use capacity! For data and strings, this is safe, as we can - * check if we still have enough bytes left. For a dictionary however, - * we can't know this, as every key / value can be more than one byte. - */ - *object = [OFMutableDictionary dictionary]; - - for (size_t i = 0; i < count; i++) { - id key, value; - - pool = objc_autoreleasePoolPush(); - - pos += parseObject(buffer + pos, length - pos, &key, - depthLimit); - pos += parseObject(buffer + pos, length - pos, &value, - depthLimit); - - [*object setObject: value - forKey: key]; - - objc_autoreleasePoolPop(pool); - } - - return pos; -} - -static OFDate * -createDate(OFData *data) -{ - switch (data.count) { - case 4: { - uint32_t timestamp; - - memcpy(×tamp, data.items, 4); - timestamp = OF_BSWAP32_IF_LE(timestamp); - - return [OFDate dateWithTimeIntervalSince1970: timestamp]; - } - case 8: { - uint64_t combined; - - memcpy(&combined, data.items, 8); - combined = OF_BSWAP64_IF_LE(combined); - - return [OFDate dateWithTimeIntervalSince1970: - (double)(combined & 0x3FFFFFFFF) + - (double)(combined >> 34) / 1000000000]; - } - case 12: { - uint32_t nanoseconds; - int64_t seconds; - - memcpy(&nanoseconds, data.items, 4); - memcpy(&seconds, (char *)data.items + 4, 8); - - nanoseconds = OF_BSWAP32_IF_LE(nanoseconds); - seconds = OF_BSWAP64_IF_LE(seconds); - - return [OFDate dateWithTimeIntervalSince1970: - (double)seconds + (double)nanoseconds / 1000000000]; - } - default: - @throw [OFInvalidFormatException exception]; - } -} - -static id -createExtension(int8_t type, OFData *data) -{ - switch (type) { - case -1: - return createDate(data); - default: - return [OFMessagePackExtension extensionWithType: type - data: data]; - } -} - -static size_t -parseObject(const unsigned char *buffer, size_t length, id *object, - size_t depthLimit) -{ - size_t count; - OFData *data; - - if (length < 1) - @throw [OFTruncatedDataException exception]; - - /* positive fixint */ - if ((buffer[0] & 0x80) == 0) { - *object = [OFNumber numberWithUInt8: buffer[0] & 0x7F]; - return 1; - } - /* negative fixint */ - if ((buffer[0] & 0xE0) == 0xE0) { - *object = [OFNumber numberWithInt8: - ((int8_t)(buffer[0] & 0x1F)) - 32]; - return 1; - } - - /* fixstr */ - if ((buffer[0] & 0xE0) == 0xA0) { - count = buffer[0] & 0x1F; - - if (length < count + 1) - @throw [OFTruncatedDataException exception]; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 1 - length: count]; - return count + 1; - } - - /* fixarray */ - if ((buffer[0] & 0xF0) == 0x90) - return parseArray(buffer + 1, length - 1, object, - buffer[0] & 0xF, depthLimit) + 1; - - /* fixmap */ - if ((buffer[0] & 0xF0) == 0x80) - return parseTable(buffer + 1, length - 1, object, - buffer[0] & 0xF, depthLimit) + 1; - - /* Prefix byte */ - switch (buffer[0]) { - /* Unsigned integers */ - case 0xCC: /* uint8 */ - if (length < 2) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithUInt8: buffer[1]]; - return 2; - case 0xCD: /* uint 16 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithUInt16: readUInt16(buffer + 1)]; - return 3; - case 0xCE: /* uint 32 */ - if (length < 5) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithUInt32: readUInt32(buffer + 1)]; - return 5; - case 0xCF: /* uint 64 */ - if (length < 9) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithUInt64: readUInt64(buffer + 1)]; - return 9; - /* Signed integers */ - case 0xD0: /* int 8 */ - if (length < 2) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithInt8: buffer[1]]; - return 2; - case 0xD1: /* int 16 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithInt16: readUInt16(buffer + 1)]; - return 3; - case 0xD2: /* int 32 */ - if (length < 5) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithInt32: readUInt32(buffer + 1)]; - return 5; - case 0xD3: /* int 64 */ - if (length < 9) - @throw [OFTruncatedDataException exception]; - - *object = [OFNumber numberWithInt64: readUInt64(buffer + 1)]; - return 9; - /* Floating point */ - case 0xCA:; /* float 32 */ - float f; - - if (length < 5) - @throw [OFTruncatedDataException exception]; - - memcpy(&f, buffer + 1, 4); - - *object = [OFNumber numberWithFloat: OF_BSWAP_FLOAT_IF_LE(f)]; - return 5; - case 0xCB:; /* float 64 */ - double d; - - if (length < 9) - @throw [OFTruncatedDataException exception]; - - memcpy(&d, buffer + 1, 8); - - *object = [OFNumber numberWithDouble: OF_BSWAP_DOUBLE_IF_LE(d)]; - return 9; - /* nil */ - case 0xC0: - *object = [OFNull null]; - return 1; - /* false */ - case 0xC2: - *object = [OFNumber numberWithBool: false]; - return 1; - /* true */ - case 0xC3: - *object = [OFNumber numberWithBool: true]; - return 1; - /* Data */ - case 0xC4: /* bin 8 */ - if (length < 2) - @throw [OFTruncatedDataException exception]; - - count = buffer[1]; - - if (length < count + 2) - @throw [OFTruncatedDataException exception]; - - *object = [OFData dataWithItems: buffer + 2 - count: count]; - - return count + 2; - case 0xC5: /* bin 16 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - count = readUInt16(buffer + 1); - - if (length < count + 3) - @throw [OFTruncatedDataException exception]; - - *object = [OFData dataWithItems: buffer + 3 - count: count]; - - return count + 3; - case 0xC6: /* bin 32 */ - if (length < 5) - @throw [OFTruncatedDataException exception]; - - count = readUInt32(buffer + 1); - - if (length < count + 5) - @throw [OFTruncatedDataException exception]; - - *object = [OFData dataWithItems: buffer + 5 - count: count]; - - return count + 5; - /* Extensions */ - case 0xC7: /* ext 8 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - count = buffer[1]; - - if (length < count + 3) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 3 - count: count]; - @try { - *object = createExtension(buffer[2], data); - } @finally { - [data release]; - } - - return count + 3; - case 0xC8: /* ext 16 */ - if (length < 4) - @throw [OFTruncatedDataException exception]; - - count = readUInt16(buffer + 1); - - if (length < count + 4) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 4 - count: count]; - @try { - *object = createExtension(buffer[3], data); - } @finally { - [data release]; - } - - return count + 4; - case 0xC9: /* ext 32 */ - if (length < 6) - @throw [OFTruncatedDataException exception]; - - count = readUInt32(buffer + 1); - - if (length < count + 6) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 6 - count: count]; - @try { - *object = createExtension(buffer[5], data); - } @finally { - [data release]; - } - - return count + 6; - case 0xD4: /* fixext 1 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 2 - count: 1]; - @try { - *object = createExtension(buffer[1], data); - } @finally { - [data release]; - } - - return 3; - case 0xD5: /* fixext 2 */ - if (length < 4) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 2 - count: 2]; - @try { - *object = createExtension(buffer[1], data); - } @finally { - [data release]; - } - - return 4; - case 0xD6: /* fixext 4 */ - if (length < 6) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 2 - count: 4]; - @try { - *object = createExtension(buffer[1], data); - } @finally { - [data release]; - } - - return 6; - case 0xD7: /* fixext 8 */ - if (length < 10) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 2 - count: 8]; - @try { - *object = createExtension(buffer[1], data); - } @finally { - [data release]; - } - - return 10; - case 0xD8: /* fixext 16 */ - if (length < 18) - @throw [OFTruncatedDataException exception]; - - data = [[OFData alloc] initWithItems: buffer + 2 - count: 16]; - @try { - *object = createExtension(buffer[1], data); - } @finally { - [data release]; - } - - return 18; - /* Strings */ - case 0xD9: /* str 8 */ - if (length < 2) - @throw [OFTruncatedDataException exception]; - - count = buffer[1]; - - if (length < count + 2) - @throw [OFTruncatedDataException exception]; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 2 - length: count]; - return count + 2; - case 0xDA: /* str 16 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - count = readUInt16(buffer + 1); - - if (length < count + 3) - @throw [OFTruncatedDataException exception]; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 3 - length: count]; - return count + 3; - case 0xDB: /* str 32 */ - if (length < 5) - @throw [OFTruncatedDataException exception]; - - count = readUInt32(buffer + 1); - - if (length < count + 5) - @throw [OFTruncatedDataException exception]; - - *object = [OFString - stringWithUTF8String: (const char *)buffer + 5 - length: count]; - return count + 5; - /* Arrays */ - case 0xDC: /* array 16 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - return parseArray(buffer + 3, length - 3, object, - readUInt16(buffer + 1), depthLimit) + 3; - case 0xDD: /* array 32 */ - if (length < 5) - @throw [OFTruncatedDataException exception]; - - return parseArray(buffer + 5, length - 5, object, - readUInt32(buffer + 1), depthLimit) + 5; - /* Maps */ - case 0xDE: /* map 16 */ - if (length < 3) - @throw [OFTruncatedDataException exception]; - - return parseTable(buffer + 3, length - 3, object, - readUInt16(buffer + 1), depthLimit) + 3; - case 0xDF: /* map 32 */ - if (length < 5) - @throw [OFTruncatedDataException exception]; - - return parseTable(buffer + 5, length - 5, object, - readUInt32(buffer + 1), depthLimit) + 5; - default: - @throw [OFInvalidFormatException exception]; - } -} - -@implementation OFData (MessagePackValue) -- (id)messagePackValue -{ - return [self messagePackValueWithDepthLimit: 32]; -} - -- (id)messagePackValueWithDepthLimit: (size_t)depthLimit -{ - void *pool = objc_autoreleasePoolPush(); - size_t count = self.count; - id object; - - if (self.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - if (parseObject(self.items, count, &object, depthLimit) != count) - @throw [OFInvalidFormatException exception]; - - [object retain]; - - objc_autoreleasePoolPop(pool); - - return [object autorelease]; -} -@end Index: src/OFData.h ================================================================== --- src/OFData.h +++ src/OFData.h @@ -26,11 +26,11 @@ enum { OF_DATA_SEARCH_BACKWARDS = 1 }; -/*! +/** * @class OFData OFData.h ObjFW/OFData.h * * @brief A class for storing arbitrary data in an array. * * For security reasons, serialization and deserialization is only implemented @@ -42,66 +42,66 @@ unsigned char *_items; size_t _count, _itemSize; bool _freeWhenDone; @private OFData *_parentData; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFData, 4) } -/*! +/** * @brief The size of a single item in the OFData in bytes. */ @property (readonly, nonatomic) size_t itemSize; -/*! +/** * @brief The number of items in the OFData. */ @property (readonly, nonatomic) size_t count; -/*! +/** * @brief All elements of the OFData as a C array. * * @warning The pointer is only valid until the OFData is changed! */ @property (readonly, nonatomic) const void *items OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The first item of the OFData or `NULL`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) const void *firstItem OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The last item of the OFData or `NULL`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) const void *lastItem OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The string representation of the data. * * The string representation is a hex dump of the data, grouped by itemSize * bytes. */ @property (readonly, nonatomic) OFString *stringRepresentation; -/*! +/** * @brief A string containing the data in Base64 encoding. */ @property (readonly, nonatomic) OFString *stringByBase64Encoding; -/*! +/** * @brief Creates a new OFData with the specified `count` items of size 1. * * @param items The items to store in the OFData * @param count The number of items * @return A new autoreleased OFData */ + (instancetype)dataWithItems: (const void *)items count: (size_t)count; -/*! +/** * @brief Creates a new OFData with the specified `count` items of the * specified size. * * @param items The items to store in the OFData * @param itemSize The item size of a single item in bytes @@ -110,11 +110,11 @@ */ + (instancetype)dataWithItems: (const void *)items itemSize: (size_t)itemSize count: (size_t)count; -/*! +/** * @brief Creates a new OFData with the specified `count` items of size 1 by * taking over ownership of the specified items pointer. * * @param items The items to store in the OFData * @param count The number of items @@ -124,11 +124,11 @@ */ + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone; -/*! +/** * @brief Creates a new OFData with the specified `count` items of the * specified size by taking ownership of the specified items pointer. * * @param items The items to store in the OFData * @param itemSize The item size of a single item in bytes @@ -141,48 +141,48 @@ itemSize: (size_t)itemSize count: (size_t)count freeWhenDone: (bool)freeWhenDone; #ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a new OFData with an item size of 1, containing the data of * the specified file. * * @param path The path of the file * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfFile: (OFString *)path; #endif -/*! +/** * @brief Creates a new OFData with an item size of 1, containing the data of * the specified URL. * * @param URL The URL to the contents for the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfURL: (OFURL *)URL; -/*! +/** * @brief Creates a new OFData with an item size of 1, containing the data of * the string representation. * * @param string The string representation of the data * @return A new autoreleased OFData */ + (instancetype)dataWithStringRepresentation: (OFString *)string; -/*! +/** * @brief Creates a new OFData with an item size of 1, containing the data of * the Base64-encoded string. * * @param string The string with the Base64-encoded data * @return A new autoreleased OFData */ + (instancetype)dataWithBase64EncodedString: (OFString *)string; -/*! +/** * @brief Initialized an already allocated OFData with the specified `count` * items of size 1. * * @param items The items to store in the OFData * @param count The number of items @@ -189,11 +189,11 @@ * @return An initialized OFData */ - (instancetype)initWithItems: (const void *)items count: (size_t)count; -/*! +/** * @brief Initialized an already allocated OFData with the specified `count` * items of the specified size. * * @param items The items to store in the OFData * @param itemSize The item size of a single item in bytes @@ -202,11 +202,11 @@ */ - (instancetype)initWithItems: (const void *)items itemSize: (size_t)itemSize count: (size_t)count; -/*! +/** * @brief Initializes an already allocated OFData with the specified `count` * items of size 1 by taking over ownership of the specified items * pointer. * * @param items The items to store in the OFData @@ -217,11 +217,11 @@ */ - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone; -/*! +/** * @brief Initializes an already allocated OFData with the specified `count` * items of the specified size by taking ownership of the specified * items pointer. * * @param items The items to store in the OFData @@ -235,64 +235,64 @@ itemSize: (size_t)itemSize count: (size_t)count freeWhenDone: (bool)freeWhenDone; #ifdef OF_HAVE_FILES -/*! +/** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the specified file. * * @param path The path of the file * @return An initialized OFData */ - (instancetype)initWithContentsOfFile: (OFString *)path; #endif -/*! +/** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the specified URL. * * @param URL The URL to the contents for the OFData * @return A new autoreleased OFData */ - (instancetype)initWithContentsOfURL: (OFURL *)URL; -/*! +/** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the string representation. * * @param string The string representation of the data * @return A new autoreleased OFData */ - (instancetype)initWithStringRepresentation: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the Base64-encoded string. * * @param string The string with the Base64-encoded data * @return An initialized OFData */ - (instancetype)initWithBase64EncodedString: (OFString *)string; -/*! +/** * @brief Returns a specific item of the OFData. * * @param index The number of the item to return * @return The specified item of the OFData */ - (const void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Returns the data in the specified range as a new OFData. * * @param range The range of the data for the new OFData * @return The data in the specified range as a new OFData */ - (OFData *)subdataWithRange: (of_range_t)range; -/*! +/** * @brief Returns the range of the data. * * @param data The data to search for * @param options Options modifying search behavior.@n * Possible values are: @@ -306,19 +306,19 @@ - (of_range_t)rangeOfData: (OFData *)data options: (int)options range: (of_range_t)range; #ifdef OF_HAVE_FILES -/*! +/** * @brief Writes the OFData into the specified file. * * @param path The path of the file to write to */ - (void)writeToFile: (OFString *)path; #endif -/*! +/** * @brief Writes the OFData to the specified URL. * * @param URL The URL to write to */ - (void)writeToURL: (OFURL *)URL; @@ -325,8 +325,8 @@ @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" -#import "OFData+ASN1DERValue.h" +#import "OFData+ASN1DERParsing.h" #import "OFData+CryptoHashing.h" -#import "OFData+MessagePackValue.h" +#import "OFData+MessagePackParsing.h" Index: src/OFData.m ================================================================== --- src/OFData.m +++ src/OFData.m @@ -46,13 +46,13 @@ /* References for static linking */ void _references_to_categories_of_OFData(void) { - _OFData_ASN1DERValue_reference = 1; + _OFData_ASN1DERParsing_reference = 1; _OFData_CryptoHashing_reference = 1; - _OFData_MessagePackValue_reference = 1; + _OFData_MessagePackParsing_reference = 1; } @implementation OFData @synthesize itemSize = _itemSize; @@ -182,19 +182,19 @@ #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { char *buffer = NULL; - uintmax_t size; + unsigned long long size; @try { OFFile *file; size = [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; -# if UINTMAX_MAX > SIZE_MAX +# if ULLONG_MAX > SIZE_MAX if (size > SIZE_MAX) @throw [OFOutOfRangeException exception]; # endif if ((buffer = malloc((size_t)size)) == NULL) Index: src/OFDatagramSocket.h ================================================================== --- src/OFDatagramSocket.h +++ src/OFDatagramSocket.h @@ -21,17 +21,17 @@ #import "socket.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFData; @class OFDatagramSocket; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when a packet has been received. * * @param length The length of the packet * @param sender The address of the sender of the packet * @param exception An exception which occurred while receiving or `nil` on @@ -40,11 +40,11 @@ */ typedef bool (^of_datagram_socket_async_receive_block_t)( size_t length, const of_socket_address_t *_Nonnull sender, id _Nullable exception); -/*! +/** * @brief A block which is called when a packet has been sent. * * @param data The data which was sent * @param receiver The receiver for the packet * @param exception An exception which occurred while reading or `nil` on @@ -54,19 +54,19 @@ typedef OFData *_Nullable (^of_datagram_socket_async_send_data_block_t)( OFData *_Nonnull data, const of_socket_address_t *_Nonnull receiver, id _Nullable exception); #endif -/*! +/** * @protocol OFDatagramSocketDelegate OFDatagramSocket.h \ * ObjFW/OFDatagramSocket.h * * @brief A delegate for OFDatagramSocket. */ @protocol OFDatagramSocketDelegate @optional -/*! +/** * @brief This method is called when a packet has been received. * * @param socket The datagram socket which received a packet * @param buffer The buffer the packet has been written to * @param length The length of the packet @@ -79,11 +79,11 @@ didReceiveIntoBuffer: (void *)buffer length: (size_t)length sender: (const of_socket_address_t *_Nonnull)sender exception: (nullable id)exception; -/*! +/** * @brief This method is called when a packet has been sent. * * @param socket The datagram socket which sent a packet * @param data The data which was sent * @param receiver The receiver for the packet @@ -94,11 +94,11 @@ didSendData: (OFData *)data receiver: (const of_socket_address_t *_Nonnull)receiver exception: (nullable id)exception; @end -/*! +/** * @class OFDatagramSocket OFDatagramSocket.h ObjFW/OFDatagramSocket.h * * @brief A base class for datagram sockets. * * @warning Even though the OFCopying protocol is implemented, it does *not* @@ -115,42 +115,42 @@ bool _canBlock; #ifdef OF_WII bool _canSendToBroadcastAddresses; #endif id _Nullable _delegate; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFDatagramSocket, 4) } -/*! +/** * @brief Whether the socket can block. * * By default, a socket can block. */ @property (nonatomic) bool canBlock; -/*! +/** * @brief Whether the socket can send to broadcast addresses. */ @property (nonatomic) bool canSendToBroadcastAddresses; -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Returns a new, autoreleased OFDatagramSocket. * * @return A new, autoreleased OFDatagramSocket */ + (instancetype)socket; -/*! +/** * @brief Receives a datagram and stores it into the specified buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to @@ -161,11 +161,11 @@ */ - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length sender: (of_socket_address_t *)sender; -/*! +/** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * @@ -173,11 +173,11 @@ * @param length The length of the buffer */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length; -/*! +/** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * @@ -188,11 +188,11 @@ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * @@ -207,11 +207,11 @@ */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (of_datagram_socket_async_receive_block_t)block; -/*! +/** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * @@ -229,11 +229,11 @@ length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_datagram_socket_async_receive_block_t)block; #endif -/*! +/** * @brief Sends the specified datagram to the specified address. * * @param buffer The buffer to send as a datagram * @param length The length of the buffer * @param receiver A pointer to an @ref of_socket_address_t to which the @@ -241,21 +241,21 @@ */ - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_socket_address_t *)receiver; -/*! +/** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. */ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver; -/*! +/** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. @@ -264,11 +264,11 @@ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. @@ -278,11 +278,11 @@ */ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver block: (of_datagram_socket_async_send_data_block_t)block; -/*! +/** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. @@ -295,18 +295,18 @@ receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_datagram_socket_async_send_data_block_t)block; #endif -/*! +/** * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; -/*! +/** * @brief Closes the socket so that it can neither receive nor send any more * datagrams. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFDate.h ================================================================== --- src/OFDate.h +++ src/OFDate.h @@ -22,16 +22,18 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFConstantString; -/*! +/** * @class OFDate OFDate.h ObjFW/OFDate.h * * @brief A class for storing, accessing and comparing dates. */ +#ifndef OF_DATE_M OF_SUBCLASSING_RESTRICTED +#endif @interface OFDate: OFObject { of_time_interval_t _seconds; } @@ -39,125 +41,125 @@ #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFDate *distantFuture; @property (class, readonly, nonatomic) OFDate *distantPast; #endif -/*! +/** * @brief The microsecond of the date. */ @property (readonly, nonatomic) uint32_t microsecond; -/*! +/** * @brief The second of the date. */ @property (readonly, nonatomic) uint8_t second; -/*! +/** * @brief The minute of the date. */ @property (readonly, nonatomic) uint8_t minute; -/*! +/** * @brief The minute of the date in local time. */ @property (readonly, nonatomic) uint8_t localMinute; -/*! +/** * @brief The hour of the date. */ @property (readonly, nonatomic) uint8_t hour; -/*! +/** * @brief The hour of the date in local time. */ @property (readonly, nonatomic) uint8_t localHour; -/*! +/** * @brief The day of the month of the date. */ @property (readonly, nonatomic) uint8_t dayOfMonth; -/*! +/** * @brief The day of the month of the date in local time. */ @property (readonly, nonatomic) uint8_t localDayOfMonth; -/*! +/** * @brief The month of the year of the date. */ @property (readonly, nonatomic) uint8_t monthOfYear; -/*! +/** * @brief The month of the year of the date in local time. */ @property (readonly, nonatomic) uint8_t localMonthOfYear; -/*! +/** * @brief The year of the date. */ @property (readonly, nonatomic) uint16_t year; -/*! +/** * @brief The year of the date in local time. */ @property (readonly, nonatomic) uint16_t localYear; -/*! +/** * @brief The day of the week of the date. */ @property (readonly, nonatomic) uint8_t dayOfWeek; -/*! +/** * @brief The day of the week of the date in local time. */ @property (readonly, nonatomic) uint8_t localDayOfWeek; -/*! +/** * @brief The day of the year of the date. */ @property (readonly, nonatomic) uint16_t dayOfYear; -/*! +/** * @brief The day of the year of the date in local time. */ @property (readonly, nonatomic) uint16_t localDayOfYear; -/*! +/** * @brief The seconds since 1970-01-01T00:00:00Z. */ @property (readonly, nonatomic) of_time_interval_t timeIntervalSince1970; -/*! +/** * @brief The seconds the date is in the future. */ @property (readonly, nonatomic) of_time_interval_t timeIntervalSinceNow; -/*! +/** * @brief Creates a new OFDate with the current date and time. * * @return A new, autoreleased OFDate with the current date and time */ + (instancetype)date; -/*! +/** * @brief Creates a new OFDate with the specified date and time since * 1970-01-01T00:00:00Z. * * @param seconds The seconds since 1970-01-01T00:00:00Z * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithTimeIntervalSince1970: (of_time_interval_t)seconds; -/*! +/** * @brief Creates a new OFDate with the specified date and time since now. * * @param seconds The seconds since now * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithTimeIntervalSinceNow: (of_time_interval_t)seconds; -/*! +/** * @brief Creates a new OFDate with the specified string in the specified * format. * * The time zone used is UTC. See @ref dateWithLocalDateString:format: if you * want local time. @@ -173,11 +175,11 @@ * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithDateString: (OFString *)string format: (OFString *)format; -/*! +/** * @brief Creates a new OFDate with the specified string in the specified * format. * * See the man page for `strftime` for information on the format. * @@ -190,47 +192,48 @@ * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithLocalDateString: (OFString *)string format: (OFString *)format; -/*! +/** * @brief Returns a date in the distant future. * * The date is system-dependant. * * @return A date in the distant future */ + (instancetype)distantFuture; -/*! +/** * @brief Returns a date in the distant past. * * The date is system-dependant. * * @return A date in the distant past */ + (instancetype)distantPast; -/*! +/** * @brief Initializes an already allocated OFDate with the specified date and * time since 1970-01-01T00:00:00Z. * * @param seconds The seconds since 1970-01-01T00:00:00Z * @return An initialized OFDate with the specified date and time */ -- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds; +- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds + OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Initializes an already allocated OFDate with the specified date and * time since now. * * @param seconds The seconds since now * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithTimeIntervalSinceNow: (of_time_interval_t)seconds; -/*! +/** * @brief Initializes an already allocated OFDate with the specified string in * the specified format. * * The time zone used is UTC. If a time zone is specified anyway, an * OFInvalidFormatException is thrown. See @ref initWithLocalDateString:format: @@ -246,11 +249,11 @@ * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format; -/*! +/** * @brief Initializes an already allocated OFDate with the specified string in * the specified format. * * If no time zone is specified, local time is assumed. * @@ -264,63 +267,63 @@ * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format; -/*! +/** * @brief Creates a string of the date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString */ - (OFString *)dateStringWithFormat: (OFConstantString *)format; -/*! +/** * @brief Creates a string of the local date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString */ - (OFString *)localDateStringWithFormat: (OFConstantString *)format; -/*! +/** * @brief Returns the earlier of the two dates. * * If the argument is `nil`, it returns the receiver. * * @param otherDate Another date * @return The earlier date of the two dates */ - (OFDate *)earlierDate: (nullable OFDate *)otherDate; -/*! +/** * @brief Returns the later of the two dates. * * If the argument is `nil`, it returns the receiver. * * @param otherDate Another date * @return The later date of the two dates */ - (OFDate *)laterDate: (nullable OFDate *)otherDate; -/*! +/** * @brief Returns the seconds the receiver is after the date. * * @param otherDate Date date to generate the difference with receiver * @return The seconds the receiver is after the date. */ - (of_time_interval_t)timeIntervalSinceDate: (OFDate *)otherDate; -/*! +/** * @brief Creates a new date with the specified time interval added. * * @param seconds The seconds after the date * @return A new, autoreleased OFDate */ - (OFDate *)dateByAddingTimeInterval: (of_time_interval_t)seconds; @end OF_ASSUME_NONNULL_END Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -12,10 +12,12 @@ * 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. */ + +#define OF_DATE_M #include "config.h" #include #include @@ -35,18 +37,77 @@ #import "OFXMLElement.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" +#import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "of_strptime.h" #ifdef OF_AMIGAOS_M68K /* amiga-gcc does not have trunc() */ # define trunc(x) ((int64_t)(x)) #endif + +@interface OFDate () ++ (instancetype)of_alloc; +@end + +@interface OFDateSingleton: OFDate +@end + +@interface OFDatePlaceholder: OFDateSingleton +@end + +#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX +@interface OFTaggedPointerDate: OFDateSingleton +@end +#endif + +static struct { + Class isa; +} placeholder; + +static OFDateSingleton *zeroDate, *distantFuture, *distantPast; +#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX +static int dateTag; +#endif + +static void +initZeroDate(void) +{ + zeroDate = [[OFDateSingleton alloc] initWithTimeIntervalSince1970: 0]; +} + +static void +initDistantFuture(void) +{ + distantFuture = [[OFDateSingleton alloc] + initWithTimeIntervalSince1970: 64060588800.0]; +} + +static void +initDistantPast(void) +{ + distantPast = [[OFDateSingleton alloc] + initWithTimeIntervalSince1970: -62167219200.0]; +} + +static of_time_interval_t +now(void) +{ + struct timeval tv; + of_time_interval_t seconds; + + OF_ENSURE(gettimeofday(&tv, NULL) == 0); + + seconds = tv.tv_sec; + seconds += (of_time_interval_t)tv.tv_usec / 1000000; + + return seconds; +} #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) static OFMutex *mutex; #endif @@ -55,38 +116,41 @@ static __time64_t (*func__mktime64)(struct tm *); #endif #ifdef HAVE_GMTIME_R # define GMTIME_RET(field) \ - time_t seconds = (time_t)_seconds; \ + of_time_interval_t timeInterval = self.timeIntervalSince1970; \ + time_t seconds = (time_t)timeInterval; \ struct tm tm; \ \ - if (seconds != trunc(_seconds)) \ + if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if (gmtime_r(&seconds, &tm) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm.field; # define LOCALTIME_RET(field) \ - time_t seconds = (time_t)_seconds; \ + of_time_interval_t timeInterval = self.timeIntervalSince1970; \ + time_t seconds = (time_t)timeInterval; \ struct tm tm; \ \ - if (seconds != trunc(_seconds)) \ + if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if (localtime_r(&seconds, &tm) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm.field; #else # ifdef OF_HAVE_THREADS # define GMTIME_RET(field) \ - time_t seconds = (time_t)_seconds; \ + of_time_interval_t timeInterval = self.timeIntervalSince1970; \ + time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ - if (seconds != trunc(_seconds)) \ + if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ [mutex lock]; \ \ @try { \ @@ -96,14 +160,15 @@ return tm->field; \ } @finally { \ [mutex unlock]; \ } # define LOCALTIME_RET(field) \ - time_t seconds = (time_t)_seconds; \ + of_time_interval_t timeInterval = self.timeIntervalSince1970; \ + time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ - if (seconds != trunc(_seconds)) \ + if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ [mutex lock]; \ \ @try { \ @@ -114,25 +179,27 @@ } @finally { \ [mutex unlock]; \ } # else # define GMTIME_RET(field) \ - time_t seconds = (time_t)_seconds; \ + of_time_interval_t timeInterval = self.timeIntervalSince1970; \ + time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ - if (seconds != trunc(_seconds)) \ + if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if ((tm = gmtime(&seconds)) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm->field; # define LOCALTIME_RET(field) \ - time_t seconds = (time_t)_seconds; \ + of_time_interval_t timeInterval = self.timeIntervalSince1970; \ + time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ - if (seconds != trunc(_seconds)) \ + if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if ((tm = localtime(&seconds)) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ @@ -186,10 +253,85 @@ /* Time zone */ seconds += -(double)*tz * 60; return seconds; } + +@implementation OFDateSingleton +- (instancetype)autorelease +{ + return self; +} + +- (instancetype)retain +{ + return self; +} + +- (void)release +{ +} + +- (unsigned int)retainCount +{ + return OF_RETAIN_COUNT_MAX; +} +@end + +@implementation OFDatePlaceholder +#ifdef __clang__ +/* We intentionally don't call into super, so silence the warning. */ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunknown-pragmas" +# pragma clang diagnostic ignored "-Wobjc-designated-initializers" +#endif +- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds +{ +#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX + uint64_t value; +#endif + + if (seconds == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, initZeroDate); + return (id)zeroDate; + } + +#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX + value = OF_BSWAP64_IF_LE(OF_DOUBLE_TO_INT_RAW(OF_BSWAP_DOUBLE_IF_LE( + seconds))); + + /* Almost all dates fall into this range. */ + if (value & (UINT64_C(4) << 60)) { + id ret = objc_createTaggedPointer(dateTag, + value & ~(UINT64_C(4) << 60)); + + if (ret != nil) + return ret; + } +#endif + + return (id)[[OFDate of_alloc] initWithTimeIntervalSince1970: seconds]; +} +#ifdef __clang__ +# pragma clang diagnostic pop +#endif +@end + +#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX +@implementation OFTaggedPointerDate +- (of_time_interval_t)timeIntervalSince1970 +{ + uint64_t value = (uint64_t)object_getTaggedPointerValue(self); + + value |= UINT64_C(4) << 60; + + return OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE( + value))); +} +@end +#endif @implementation OFDate + (void)initialize { #ifdef OF_WINDOWS @@ -196,10 +338,12 @@ HMODULE module; #endif if (self != [OFDate class]) return; + + placeholder.isa = [OFDatePlaceholder class]; #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) mutex = [[OFMutex alloc] init]; #endif @@ -207,10 +351,27 @@ #ifdef OF_WINDOWS if ((module = LoadLibrary("msvcrt.dll")) != NULL) func__mktime64 = (__time64_t (*)(struct tm *)) GetProcAddress(module, "_mktime64"); #endif + +#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX + dateTag = objc_registerTaggedPointerClass([OFTaggedPointerDate class]); +#endif +} + ++ (instancetype)of_alloc +{ + return [super alloc]; +} + ++ (instancetype)alloc +{ + if (self == [OFDate class]) + return (id)&placeholder; + + return [super alloc]; } + (instancetype)date { return [[[self alloc] init] autorelease]; @@ -242,32 +403,25 @@ format: format] autorelease]; } + (instancetype)distantFuture { - return [[[self alloc] - initWithTimeIntervalSince1970: 64060588800.0] autorelease]; + static of_once_t once = OF_ONCE_INIT; + of_once(&once, initDistantFuture); + return distantFuture; } + (instancetype)distantPast { - return [[[self alloc] - initWithTimeIntervalSince1970: -62167219200.0] autorelease]; + static of_once_t once = OF_ONCE_INIT; + of_once(&once, initDistantPast); + return distantPast; } - (instancetype)init { - struct timeval t; - - self = [super init]; - - OF_ENSURE(gettimeofday(&t, NULL) == 0); - - _seconds = t.tv_sec; - _seconds += (of_time_interval_t)t.tv_usec / 1000000; - - return self; + return [self initWithTimeIntervalSince1970: now()]; } - (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds { self = [super init]; @@ -277,108 +431,95 @@ return self; } - (instancetype)initWithTimeIntervalSinceNow: (of_time_interval_t)seconds { - self = [self init]; - - _seconds += seconds; - - return self; + return [self initWithTimeIntervalSince1970: now() + seconds]; } - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format { - self = [super init]; - - @try { - const char *UTF8String = string.UTF8String; - struct tm tm = { 0 }; - int16_t tz = 0; - - tm.tm_isdst = -1; - - if (of_strptime(UTF8String, format.UTF8String, - &tm, &tz) != UTF8String + string.UTF8StringLength) - @throw [OFInvalidFormatException exception]; - - _seconds = tmAndTzToTime(&tm, &tz); - } @catch (id e) { - [self release]; - @throw e; - } - - return self; + void *pool = objc_autoreleasePoolPush(); + const char *UTF8String = string.UTF8String; + struct tm tm = { .tm_isdst = -1 }; + int16_t 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)]; } - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format { - self = [super init]; - - @try { - const char *UTF8String = string.UTF8String; - struct tm tm = { 0 }; - /* - * of_strptime() can never set this to INT16_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; - - tm.tm_isdst = -1; - - if (of_strptime(UTF8String, format.UTF8String, - &tm, &tz) != UTF8String + string.UTF8StringLength) - @throw [OFInvalidFormatException exception]; - - if (tz == INT16_MAX) { -#ifdef OF_WINDOWS - if (func__mktime64 != NULL) { - if ((_seconds = func__mktime64(&tm)) == -1) - @throw [OFInvalidFormatException - exception]; - } else { -#endif - if ((_seconds = mktime(&tm)) == -1) - @throw [OFInvalidFormatException - exception]; -#ifdef OF_WINDOWS - } -#endif - } else - _seconds = tmAndTzToTime(&tm, &tz); - } @catch (id e) { - [self release]; - @throw e; - } - - return self; + 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 + * passed to it, so this is a safe way to figure out if the date + * contains a time zone. + */ + int16_t tz = INT16_MAX; + of_time_interval_t seconds; + + if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) != + UTF8String + string.UTF8StringLength) + @throw [OFInvalidFormatException exception]; + + if (tz == INT16_MAX) { +#ifdef OF_WINDOWS + if (func__mktime64 != NULL) { + if ((seconds = func__mktime64(&tm)) == -1) + @throw [OFInvalidFormatException exception]; + } else { +#endif + if ((seconds = mktime(&tm)) == -1) + @throw [OFInvalidFormatException exception]; +#ifdef OF_WINDOWS + } +#endif + } else + seconds = tmAndTzToTime(&tm, &tz); + + objc_autoreleasePoolPop(pool); + + return [self initWithTimeIntervalSince1970: seconds]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { - self = [super init]; + of_time_interval_t seconds; @try { void *pool = objc_autoreleasePoolPush(); + unsigned long long value; - if (![element.name isEqual: self.className] || + if (![element.name isEqual: @"OFDate"] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; - _seconds = OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW( - OF_BSWAP64_IF_LE(element.hexadecimalValue))); + value = [element unsignedLongLongValueWithBase: 16]; + + if (value > UINT64_MAX) + @throw [OFOutOfRangeException exception]; + + seconds = OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW( + OF_BSWAP64_IF_LE(value))); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } - return self; + return [self initWithTimeIntervalSince1970: seconds]; } - (bool)isEqual: (id)object { OFDate *otherDate; @@ -389,11 +530,11 @@ if (![object isKindOfClass: [OFDate class]]) return false; otherDate = object; - if (otherDate->_seconds != _seconds) + if (otherDate.timeIntervalSince1970 != self.timeIntervalSince1970) return false; return true; } @@ -402,11 +543,11 @@ uint32_t hash; double tmp; OF_HASH_INIT(hash); - tmp = OF_BSWAP_DOUBLE_IF_BE(_seconds); + tmp = OF_BSWAP_DOUBLE_IF_BE(self.timeIntervalSince1970); for (size_t i = 0; i < sizeof(double); i++) OF_HASH_ADD(hash, ((char *)&tmp)[i]); OF_HASH_FINALIZE(hash); @@ -426,13 +567,13 @@ if (![(id)object isKindOfClass: [OFDate class]]) @throw [OFInvalidArgumentException exception]; otherDate = (OFDate *)object; - if (_seconds < otherDate->_seconds) + if (self.timeIntervalSince1970 < otherDate.timeIntervalSince1970) return OF_ORDERED_ASCENDING; - if (_seconds > otherDate->_seconds) + if (self.timeIntervalSince1970 > otherDate.timeIntervalSince1970) return OF_ORDERED_DESCENDING; return OF_ORDERED_SAME; } @@ -444,16 +585,16 @@ - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; - element = [OFXMLElement elementWithName: self.className + element = [OFXMLElement elementWithName: @"OFDate" namespace: OF_SERIALIZATION_NS]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OF_BSWAP64_IF_LE(OF_DOUBLE_TO_INT_RAW(OF_BSWAP_DOUBLE_IF_LE( - _seconds)))]; + self.timeIntervalSince1970)))]; [element retain]; objc_autoreleasePoolPop(pool); @@ -461,12 +602,14 @@ } - (OFData *)messagePackRepresentation { void *pool = objc_autoreleasePoolPush(); - int64_t seconds = (int64_t)_seconds; - uint32_t nanoseconds = (_seconds - trunc(_seconds)) * 1000000000; + of_time_interval_t timeInterval = self.timeIntervalSince1970; + int64_t seconds = (int64_t)timeInterval; + uint32_t nanoseconds = + (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000000); OFData *ret; if (seconds >= 0 && seconds < 0x400000000) { if (seconds <= UINT32_MAX && nanoseconds == 0) { uint32_t seconds32 = (uint32_t)seconds; @@ -515,11 +658,13 @@ return [ret autorelease]; } - (uint32_t)microsecond { - return (uint32_t)((_seconds - trunc(_seconds)) * 1000000); + of_time_interval_t timeInterval = self.timeIntervalSince1970; + + return (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000); } - (uint8_t)second { GMTIME_RET(tm_sec) @@ -596,20 +741,21 @@ } - (OFString *)dateStringWithFormat: (OFConstantString *)format { OFString *ret; - time_t seconds = (time_t)_seconds; + of_time_interval_t timeInterval = self.timeIntervalSince1970; + time_t seconds = (time_t)timeInterval; struct tm tm; size_t pageSize; #ifndef OF_WINDOWS char *buffer; #else wchar_t *buffer; #endif - if (seconds != trunc(_seconds)) + if (seconds != trunc(timeInterval)) @throw [OFOutOfRangeException exception]; #ifdef HAVE_GMTIME_R if (gmtime_r(&seconds, &tm) == NULL) @throw [OFOutOfRangeException exception]; @@ -631,11 +777,13 @@ } # endif #endif pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; + if ((buffer = malloc(pageSize)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: pageSize]; @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; @@ -647,29 +795,30 @@ @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF16String: buffer]; #endif } @finally { - [self freeMemory: buffer]; + free(buffer); } return ret; } - (OFString *)localDateStringWithFormat: (OFConstantString *)format { OFString *ret; - time_t seconds = (time_t)_seconds; + of_time_interval_t timeInterval = self.timeIntervalSince1970; + time_t seconds = (time_t)timeInterval; struct tm tm; size_t pageSize; #ifndef OF_WINDOWS char *buffer; #else wchar_t *buffer; #endif - if (seconds != trunc(_seconds)) + if (seconds != trunc(timeInterval)) @throw [OFOutOfRangeException exception]; #ifdef HAVE_LOCALTIME_R if (localtime_r(&seconds, &tm) == NULL) @throw [OFOutOfRangeException exception]; @@ -691,11 +840,13 @@ } # endif #endif pageSize = [OFSystemInfo pageSize]; - buffer = [self allocMemoryWithSize: pageSize]; + if ((buffer = malloc(pageSize)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: pageSize]; @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; @@ -707,11 +858,11 @@ @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF16String: buffer]; #endif } @finally { - [self freeMemory: buffer]; + free(buffer); } return ret; } @@ -742,11 +893,11 @@ return _seconds; } - (of_time_interval_t)timeIntervalSinceDate: (OFDate *)otherDate { - return _seconds - otherDate->_seconds; + return self.timeIntervalSince1970 - otherDate.timeIntervalSince1970; } - (of_time_interval_t)timeIntervalSinceNow { struct timeval t; @@ -755,13 +906,14 @@ OF_ENSURE(gettimeofday(&t, NULL) == 0); seconds = t.tv_sec; seconds += (of_time_interval_t)t.tv_usec / 1000000; - return _seconds - seconds; + return self.timeIntervalSince1970 - seconds; } - (OFDate *)dateByAddingTimeInterval: (of_time_interval_t)seconds { - return [OFDate dateWithTimeIntervalSince1970: _seconds + seconds]; + return [OFDate dateWithTimeIntervalSince1970: + self.timeIntervalSince1970 + seconds]; } @end Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -40,11 +40,11 @@ bool *stop); typedef bool (^of_dictionary_filter_block_t)(id key, id object); typedef id _Nonnull (^of_dictionary_map_block_t)(id key, id object); #endif -/*! +/** * @class OFDictionary OFDictionary.h ObjFW/OFDictionary.h * * @brief An abstract class for storing objects in a dictionary. * * Keys are copied and thus must conform to the OFCopying protocol. @@ -60,52 +60,52 @@ OFMessagePackRepresentation> #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define KeyType id # define ObjectType id #endif -/*! +/** * @brief An array of all keys. */ @property (readonly, nonatomic) OFArray OF_GENERIC(KeyType) *allKeys; -/*! +/** * @brief An array of all objects. */ @property (readonly, nonatomic) OFArray OF_GENERIC(ObjectType) *allObjects; -/*! +/** * @brief A URL-encoded string with the contents of the dictionary. */ @property (readonly, nonatomic) OFString *stringByURLEncoding; -/*! +/** * @brief Creates a new OFDictionary. * * @return A new autoreleased OFDictionary */ + (instancetype)dictionary; -/*! +/** * @brief Creates a new OFDictionary with the specified dictionary. * * @param dictionary An OFDictionary * @return A new autoreleased OFDictionary */ + (instancetype)dictionaryWithDictionary: (OFDictionary OF_GENERIC(KeyType, ObjectType) *)dictionary; -/*! +/** * @brief Creates a new OFDictionary with the specified key and object. * * @param key The key * @param object The object * @return A new autoreleased OFDictionary */ + (instancetype)dictionaryWithObject: (ObjectType)object forKey: (KeyType)key; -/*! +/** * @brief Creates a new OFDictionary with the specified keys and objects. * * @param keys An array of keys * @param objects An array of objects * @return A new autoreleased OFDictionary @@ -112,11 +112,11 @@ */ + (instancetype) dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects forKeys: (OFArray OF_GENERIC(KeyType) *)keys; -/*! +/** * @brief Creates a new OFDictionary with the specified keys and objects. * * @param keys An array of keys * @param objects An array of objects * @param count The number of objects in the arrays @@ -125,30 +125,30 @@ + (instancetype) dictionaryWithObjects: (ObjectType const _Nonnull *_Nonnull)objects forKeys: (KeyType const _Nonnull *_Nonnull)keys count: (size_t)count; -/*! +/** * @brief Creates a new OFDictionary with the specified keys objects. * * @param firstKey The first key * @return A new autoreleased OFDictionary */ + (instancetype)dictionaryWithKeysAndObjects: (KeyType)firstKey, ... OF_SENTINEL; -/*! +/** * @brief Initializes an already allocated OFDictionary with the specified * OFDictionary. * * @param dictionary An OFDictionary * @return An initialized OFDictionary */ - (instancetype)initWithDictionary: (OFDictionary OF_GENERIC(KeyType, ObjectType) *)dictionary; -/*! +/** * @brief Initializes an already allocated OFDictionary with the specified key * and object. * * @param key The key * @param object The object @@ -155,11 +155,11 @@ * @return An initialized OFDictionary */ - (instancetype)initWithObject: (ObjectType)object forKey: (KeyType)key; -/*! +/** * @brief Initializes an already allocated OFDictionary with the specified keys * and objects. * * @param keys An array of keys * @param objects An array of objects @@ -166,11 +166,11 @@ * @return An initialized OFDictionary */ - (instancetype)initWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects forKeys: (OFArray OF_GENERIC(KeyType) *)keys; -/*! +/** * @brief Initializes an already allocated OFDictionary with the specified keys * and objects. * * @param keys An array of keys * @param objects An array of objects @@ -179,20 +179,20 @@ */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects forKeys: (KeyType const _Nonnull *_Nonnull)keys count: (size_t)count; -/*! +/** * @brief Initializes an already allocated OFDictionary with the specified keys * and objects. * * @param firstKey The first key * @return An initialized OFDictionary */ - (instancetype)initWithKeysAndObjects: (KeyType)firstKey, ... OF_SENTINEL; -/*! +/** * @brief Initializes an already allocated OFDictionary with the specified key * and va_list. * * @param firstKey The first key * @param arguments A va_list of the other arguments @@ -199,11 +199,11 @@ * @return An initialized OFDictionary */ - (instancetype)initWithKey: (KeyType)firstKey arguments: (va_list)arguments; -/*! +/** * @brief Returns the object for the given key or `nil` if the key was not * found. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! @@ -212,11 +212,11 @@ * @return The object for the given key or `nil` if the key was not found */ - (nullable ObjectType)objectForKey: (KeyType)key; - (nullable ObjectType)objectForKeyedSubscript: (KeyType)key; -/*! +/** * @brief Returns the value for the given key or `nil` if the key was not * found. * * This is equivalent to @ref objectForKey:. * @@ -225,11 +225,11 @@ * @param key The key whose value should be returned * @return The value for the given key or `nil` if the key was not found */ - (nullable id)valueForKey: (OFString *)key; -/*! +/** * @brief Sets a value for a key. * * This is equivalent to OFMutableDictionary#setObject:forKey:. If the * dictionary is immutable, an @ref OFUndefinedKeyException is thrown. * @@ -237,63 +237,63 @@ * @param value The value to set the key to */ - (void)setValue: (nullable id)value forKey: (OFString *)key; -/*! +/** * @brief Checks whether the dictionary contains an object equal to the * specified object. * * @param object The object which is checked for being in the dictionary * @return A boolean whether the dictionary contains the specified object */ - (bool)containsObject: (ObjectType)object; -/*! +/** * @brief Checks whether the dictionary contains an object with the specified * address. * * @param object The object which is checked for being in the dictionary * @return A boolean whether the dictionary contains an object with the * specified address */ - (bool)containsObjectIdenticalTo: (ObjectType)object; -/*! +/** * @brief Returns an OFEnumerator to enumerate through the dictionary's keys. * * @return An OFEnumerator to enumerate through the dictionary's keys */ - (OFEnumerator OF_GENERIC(KeyType) *)keyEnumerator; -/*! +/** * @brief Returns an OFEnumerator to enumerate through the dictionary's objects. * * @return An OFEnumerator to enumerate through the dictionary's objects */ - (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Executes a block for each key / object pair. * * @param block The block to execute for each key / object pair. */ - (void)enumerateKeysAndObjectsUsingBlock: (of_dictionary_enumeration_block_t)block; -/*! +/** * @brief Creates a new dictionary, mapping each object using the specified * block. * * @param block A block which maps an object for each object * @return A new autoreleased OFDictionary */ - (OFDictionary OF_GENERIC(KeyType, id) *)mappedDictionaryUsingBlock: (of_dictionary_map_block_t)block; -/*! +/** * @brief Creates a new dictionary, only containing the objects for which the * block returns true. * * @param block A block which determines if the object should be in the new * dictionary Index: src/OFEnumerator.h ================================================================== --- src/OFEnumerator.h +++ src/OFEnumerator.h @@ -20,17 +20,17 @@ OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFEnumerator OF_GENERIC(ObjectType); -/*! +/** * @protocol OFEnumerating OFEnumerator.h ObjFW/OFEnumerator.h * * @brief A protocol for getting an enumerator for the object. */ @protocol OFEnumerating -/*! +/** * @brief Returns an OFEnumerator to enumerate through all objects of the * collection. * * @return An OFEnumerator to enumerate through all objects of the collection */ @@ -41,39 +41,39 @@ * This needs to be exactly like this because it's hard-coded in the compiler. * * We need this bad check to see if we already imported Cocoa, which defines * this as well. */ -/*! +/** * @struct of_fast_enumeration_state_t OFEnumerator.h ObjFW/OFEnumerator.h * * @brief State information for fast enumerations. */ #define of_fast_enumeration_state_t NSFastEnumerationState #ifndef NSINTEGER_DEFINED typedef struct { - /*! Arbitrary state information for the enumeration */ + /** Arbitrary state information for the enumeration */ unsigned long state; - /*! Pointer to a C array of objects to return */ + /** Pointer to a C array of objects to return */ id __unsafe_unretained _Nullable *_Nullable itemsPtr; - /*! Arbitrary state information to detect mutations */ + /** Arbitrary state information to detect mutations */ unsigned long *_Nullable mutationsPtr; - /*! Additional arbitrary state information */ + /** Additional arbitrary state information */ unsigned long extra[5]; } of_fast_enumeration_state_t; #endif -/*! +/** * @protocol OFFastEnumeration OFEnumerator.h ObjFW/OFEnumerator.h * * @brief A protocol for fast enumeration. * * The OFFastEnumeration protocol needs to be implemented by all classes * supporting fast enumeration. */ @protocol OFFastEnumeration -/*! +/** * @brief A method which is called by the code produced by the compiler when * doing a fast enumeration. * * @param state Context information for the enumeration * @param objects A pointer to an array where to put the objects @@ -85,31 +85,31 @@ objects: (id __unsafe_unretained _Nonnull *_Nonnull) objects count: (int)count; @end -/*! +/** * @class OFEnumerator OFEnumerator.h ObjFW/OFEnumerator.h * * @brief A class which provides methods to enumerate through collections. */ @interface OFEnumerator OF_GENERIC(ObjectType): OFObject #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFEnumerator, 4) } -/*! +/** * @brief Returns the next object or `nil` if there is none left. * * @return The next object or `nil` if there is none left */ - (nullable ObjectType)nextObject; -/*! +/** * @brief Returns an array of all remaining objects in the collection. * * @return An array of all remaining objects in the collection. */ - (OFArray OF_GENERIC(ObjectType) *)allObjects; Index: src/OFFile.h ================================================================== --- src/OFFile.h +++ src/OFFile.h @@ -29,11 +29,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFFile OFFile.h ObjFW/OFFile.h * * @brief A class which provides methods to read and write files. */ OF_SUBCLASSING_RESTRICTED @@ -44,11 +44,11 @@ { of_file_handle_t _handle; bool _atEndOfStream; } -/*! +/** * @brief Creates a new OFFile with the specified path and mode. * * @param path The path to the file to open as a string * @param mode The mode in which the file should be opened. * @n @@ -66,11 +66,11 @@ * @return A new autoreleased OFFile */ + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode; -/*! +/** * @brief Creates a new OFFile with the specified URL and mode. * * @param URL The URL to the file to open * @param mode The mode in which the file should be opened.@n * Possible modes are: @@ -87,11 +87,11 @@ * @return A new autoreleased OFFile */ + (instancetype)fileWithURL: (OFURL *)URL mode: (OFString *)mode; -/*! +/** * @brief Creates a new OFFile with the specified native file handle. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this * is a file descriptor. The handle is closed when the OFFile * object is deallocated! @@ -99,11 +99,11 @@ */ + (instancetype)fileWithHandle: (of_file_handle_t)handle; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFFile. * * @param path The path to the file to open as a string * @param mode The mode in which the file should be opened.@n * Possible modes are: @@ -124,11 +124,11 @@ * @return An initialized OFFile */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; -/*! +/** * @brief Initializes an already allocated OFFile. * * @param URL The URL to the file to open * @param mode The mode in which the file should be opened.@n * Possible modes are: @@ -149,11 +149,11 @@ * @return An initialized OFFile */ - (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode; -/*! +/** * @brief Initializes an already allocated OFFile. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this * is a file descriptor. The handle is closed when the OFFile * object is deallocated! Index: src/OFFileManager.h ================================================================== --- src/OFFileManager.h +++ src/OFFileManager.h @@ -18,11 +18,11 @@ #import "OFObject.h" #import "OFDictionary.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef OF_HAVE_FILES # if defined(OF_HAVE_CHMOD) && !defined(OF_AMIGAOS) # define OF_FILE_MANAGER_SUPPORTS_PERMISSIONS # endif @@ -41,11 +41,11 @@ @class OFConstantString; @class OFDate; @class OFString; @class OFURL; -/*! +/** * @brief A key for a file attribute in the file attributes dictionary. * * Possible keys for file URLs are: * * * @ref of_file_attribute_key_size @@ -63,11 +63,11 @@ * * Other URL schemes might not have all keys and might have keys not listed. */ typedef OFConstantString *of_file_attribute_key_t; -/*! +/** * @brief The type of a file. * * Possibles values for file URLs are: * * * @ref of_file_type_regular @@ -80,165 +80,165 @@ * * Other URL schemes might not have all types and might have types not listed. */ typedef OFConstantString *of_file_type_t; -/*! +/** * @brief A dictionary mapping keys of type @ref of_file_attribute_key_t * to their attribute values. */ typedef OFDictionary OF_GENERIC(of_file_attribute_key_t, id) *of_file_attributes_t; -/*! +/** * @brief A mutable dictionary mapping keys of type * @ref of_file_attribute_key_t to their attribute values. */ typedef OFMutableDictionary OF_GENERIC(of_file_attribute_key_t, id) *of_mutable_file_attributes_t; #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief The size of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileSize. */ extern const of_file_attribute_key_t of_file_attribute_key_size; -/*! +/** * @brief The type of the file. * * The corresponding value is of type @ref of_file_type_t. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileType. */ extern const of_file_attribute_key_t of_file_attribute_key_type; -/*! +/** * @brief The POSIX permissions of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#filePOSIXPermissions. */ extern const of_file_attribute_key_t of_file_attribute_key_posix_permissions; -/*! +/** * @brief The POSIX UID of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#filePOSIXUID. */ extern const of_file_attribute_key_t of_file_attribute_key_posix_uid; -/*! +/** * @brief The POSIX GID of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#filePOSIXGID. */ extern const of_file_attribute_key_t of_file_attribute_key_posix_gid; -/*! +/** * @brief The owner of the file as an OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileOwner. */ extern const of_file_attribute_key_t of_file_attribute_key_owner; -/*! +/** * @brief The group of the file as an OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileGroup. */ extern const of_file_attribute_key_t of_file_attribute_key_group; -/*! +/** * @brief The last access date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileLastAccessDate. */ extern const of_file_attribute_key_t of_file_attribute_key_last_access_date; -/*! +/** * @brief The last modification date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileModificationDate. */ extern const of_file_attribute_key_t of_file_attribute_key_modification_date; -/*! +/** * @brief The last status change date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileStatusChangeDate. */ extern const of_file_attribute_key_t of_file_attribute_key_status_change_date; -/*! +/** * @brief The creation date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileCreationDate. */ extern const of_file_attribute_key_t of_file_attribute_key_creation_date; -/*! +/** * @brief The destination of a symbolic link as an OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileSymbolicLinkDestination. */ extern const of_file_attribute_key_t of_file_attribute_key_symbolic_link_destination; -/*! +/** * @brief A regular file. */ extern const of_file_type_t of_file_type_regular; -/*! +/** * @brief A directory. */ extern const of_file_type_t of_file_type_directory; -/*! +/** * @brief A symbolic link. */ extern const of_file_type_t of_file_type_symbolic_link; -/*! +/** * @brief A FIFO. */ extern const of_file_type_t of_file_type_fifo; -/*! +/** * @brief A character special file. */ extern const of_file_type_t of_file_type_character_special; -/*! +/** * @brief A block special file. */ extern const of_file_type_t of_file_type_block_special; -/*! +/** * @brief A socket. */ extern const of_file_type_t of_file_type_socket; #ifdef __cplusplus } #endif -/*! +/** * @class OFFileManager OFFileManager.h ObjFW/OFFileManager.h * * @brief A class which provides management for files, e.g. reading contents of * directories, deleting files, renaming files, etc. */ @@ -249,48 +249,48 @@ #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFFileManager *defaultManager; #endif #ifdef OF_HAVE_FILES -/*! +/** * @brief The path of the current working directory. */ @property (readonly, nonatomic) OFString *currentDirectoryPath; -/*! +/** * @brief The URL of the current working directory. */ @property (readonly, nonatomic) OFURL *currentDirectoryURL; #endif -/*! +/** * @brief Returns the default file manager. */ + (OFFileManager *)defaultManager; #ifdef OF_HAVE_FILES -/*! +/** * @brief Returns the attributes for the item at the specified path. * * @param path The path to return the attributes for * @return A dictionary of attributes for the specified path, with the keys of * type @ref of_file_attribute_key_t */ - (of_file_attributes_t)attributesOfItemAtPath: (OFString *)path; #endif -/*! +/** * @brief Returns the attributes for the item at the specified URL. * * @param URL The URL to return the attributes for * @return A dictionary of attributes for the specified URL, with the keys of * type @ref of_file_attribute_key_t */ - (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Sets the attributes for the item at the specified path. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified path @@ -298,11 +298,11 @@ */ - (void)setAttributes: (of_file_attributes_t)attributes ofItemAtPath: (OFString *)path; #endif -/*! +/** * @brief Sets the attributes for the item at the specified URL. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified URL @@ -310,81 +310,81 @@ */ - (void)setAttributes: (of_file_attributes_t)attributes ofItemAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Checks whether a file exists at the specified path. * * @param path The path to check * @return A boolean whether there is a file at the specified path */ - (bool)fileExistsAtPath: (OFString *)path; #endif -/*! +/** * @brief Checks whether a file exists at the specified URL. * * @param URL The URL to check * @return A boolean whether there is a file at the specified URL */ - (bool)fileExistsAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Checks whether a directory exists at the specified path. * * @param path The path to check * @return A boolean whether there is a directory at the specified path */ - (bool)directoryExistsAtPath: (OFString *)path; #endif -/*! +/** * @brief Checks whether a directory exists at the specified URL. * * @param URL The URL to check * @return A boolean whether there is a directory at the specified URL */ - (bool)directoryExistsAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a directory at the specified path. * * @param path The path of the directory to create */ - (void)createDirectoryAtPath: (OFString *)path; -/*! +/** * @brief Creates a directory at the specified path. * * @param path The path of the directory to create * @param createParents Whether to create the parents of the directory */ - (void)createDirectoryAtPath: (OFString *)path createParents: (bool)createParents; #endif -/*! +/** * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create */ - (void)createDirectoryAtURL: (OFURL *)URL; -/*! +/** * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create * @param createParents Whether to create the parents of the directory */ - (void)createDirectoryAtURL: (OFURL *)URL createParents: (bool)createParents; #ifdef OF_HAVE_FILES -/*! +/** * @brief Returns an array with the items in the specified directory. * * @note `.` and `..` are not part of the returned array. * * @param path The path to the directory whose items should be returned @@ -391,11 +391,11 @@ * @return An array of OFString with the items in the specified directory */ - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path; #endif -/*! +/** * @brief Returns an array with the items in the specified directory. * * @note `.` and `..` are not part of the returned array. * * @param URL The URL to the directory whose items should be returned @@ -402,25 +402,25 @@ * @return An array of OFString with the items in the specified directory */ - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Changes the current working directory. * * @param path The new directory to change to */ - (void)changeCurrentDirectoryPath: (OFString *)path; -/*! +/** * @brief Changes the current working directory. * * @param URL The new directory to change to */ - (void)changeCurrentDirectoryURL: (OFURL *)URL; -/*! +/** * @brief Copies a file, directory or symbolic link (if supported by the OS). * * The destination path must be a full path, which means it must include the * name of the item. * @@ -433,11 +433,11 @@ */ - (void)copyItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif -/*! +/** * @brief Copies a file, directory or symbolic link (if supported by the OS). * * The destination URL must have a full path, which means it must include the * name of the item. * @@ -450,11 +450,11 @@ */ - (void)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination; #ifdef OF_HAVE_FILES -/*! +/** * @brief Moves an item. * * The destination path must be a full path, which means it must include the * name of the item. * @@ -467,11 +467,11 @@ */ - (void)moveItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif -/*! +/** * @brief Moves an item. * * The destination URL must have a full path, which means it must include the * name of the item. * @@ -484,31 +484,31 @@ */ - (void)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination; #ifdef OF_HAVE_FILES -/*! +/** * @brief Removes the item at the specified path. * * If the item at the specified path is a directory, it is removed recursively. * * @param path The path to the item which should be removed */ - (void)removeItemAtPath: (OFString *)path; #endif -/*! +/** * @brief Removes the item at the specified URL. * * If the item at the specified URL is a directory, it is removed recursively. * * @param URL The URL to the item which should be removed */ - (void)removeItemAtURL: (OFURL *)URL; #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS -/*! +/** * @brief Creates a hard link for the specified item. * * The destination path must be a full path, which means it must include the * name of the item. * @@ -519,11 +519,11 @@ */ - (void)linkItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif -/*! +/** * @brief Creates a hard link for the specified item. * * The destination URL must have a full path, which means it must include the * name of the item. * @@ -534,11 +534,11 @@ */ - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination; #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS -/*! +/** * @brief Creates a symbolic link for an item. * * The destination path must be a full path, which means it must include the * name of the item. * @@ -552,11 +552,11 @@ */ - (void)createSymbolicLinkAtPath: (OFString *)path withDestinationPath: (OFString *)target; #endif -/*! +/** * @brief Creates a symbolic link for an item. * * The destination uRL must have a full path, which means it must include the * name of the item. * @@ -571,96 +571,96 @@ - (void)createSymbolicLinkAtURL: (OFURL *)URL withDestinationPath: (OFString *)target; @end @interface OFDictionary (FileAttributes) -/*! +/** * @brief The @ref of_file_attribute_key_size key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ -@property (readonly, nonatomic) uintmax_t fileSize; +@property (readonly, nonatomic) unsigned long long fileSize; -/*! +/** * @brief The @ref of_file_attribute_key_type key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) of_file_type_t fileType; -/*! +/** * @brief The @ref of_file_attribute_key_posix_permissions key from the * dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ -@property (readonly, nonatomic) uint16_t filePOSIXPermissions; +@property (readonly, nonatomic) unsigned long filePOSIXPermissions; -/*! +/** * @brief The @ref of_file_attribute_key_posix_uid key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ -@property (readonly, nonatomic) uint32_t filePOSIXUID; +@property (readonly, nonatomic) unsigned long filePOSIXUID; -/*! +/** * @brief The @ref of_file_attribute_key_posix_gid key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ -@property (readonly, nonatomic) uint32_t filePOSIXGID; +@property (readonly, nonatomic) unsigned long filePOSIXGID; -/*! +/** * @brief The @ref of_file_attribute_key_owner key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFString *fileOwner; -/*! +/** * @brief The @ref of_file_attribute_key_group key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFString *fileGroup; -/*! +/** * @brief The @ref of_file_attribute_key_last_access_date key from the * dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileLastAccessDate; -/*! +/** * @brief The @ref of_file_attribute_key_modification_date key from the * dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileModificationDate; -/*! +/** * @brief The @ref of_file_attribute_key_status_change_date key from the * dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileStatusChangeDate; -/*! +/** * @brief The @ref of_file_attribute_key_creation_date key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileCreationDate; -/*! +/** * @brief The @ref of_file_attribute_key_symbolic_link_destination key from the * dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFString *fileSymbolicLinkDestination; @end OF_ASSUME_NONNULL_END Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -904,37 +904,37 @@ return OF_RETAIN_COUNT_MAX; } @end @implementation OFDictionary (FileAttributes) -- (uintmax_t)fileSize +- (unsigned long long)fileSize { return [attributeForKeyOrException(self, of_file_attribute_key_size) - uIntMaxValue]; + unsignedLongLongValue]; } - (of_file_type_t)fileType { return attributeForKeyOrException(self, of_file_attribute_key_type); } -- (uint16_t)filePOSIXPermissions -{ - return [attributeForKeyOrException(self, - of_file_attribute_key_posix_permissions) uInt16Value]; -} - -- (uint32_t)filePOSIXUID -{ - return [attributeForKeyOrException(self, - of_file_attribute_key_posix_uid) uInt32Value]; -} - -- (uint32_t)filePOSIXGID -{ - return [attributeForKeyOrException(self, - of_file_attribute_key_posix_gid) uInt32Value]; +- (unsigned long)filePOSIXPermissions +{ + return [attributeForKeyOrException(self, + of_file_attribute_key_posix_permissions) unsignedLongValue]; +} + +- (unsigned long)filePOSIXUID +{ + return [attributeForKeyOrException(self, + of_file_attribute_key_posix_uid) unsignedLongValue]; +} + +- (unsigned long)filePOSIXGID +{ + return [attributeForKeyOrException(self, + of_file_attribute_key_posix_gid) unsignedLongValue]; } - (OFString *)fileOwner { return attributeForKeyOrException(self, of_file_attribute_key_owner); Index: src/OFFileURLHandler.m ================================================================== --- src/OFFileURLHandler.m +++ src/OFFileURLHandler.m @@ -409,13 +409,13 @@ static void setOwnerAndGroupAttributes(of_mutable_file_attributes_t attributes, of_stat_t *s) { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER - [attributes setObject: [NSNumber numberWithUInt16: s->st_uid] + [attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid] forKey: of_file_attribute_key_posix_uid]; - [attributes setObject: [NSNumber numberWithUInt16: s->st_gid] + [attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid] forKey: of_file_attribute_key_posix_gid]; # ifdef OF_HAVE_THREADS [passwdMutex lock]; @try { @@ -618,16 +618,16 @@ errNo: errno]; if (s.st_size < 0) @throw [OFOutOfRangeException exception]; - [ret setObject: [NSNumber numberWithUIntMax: s.st_size] + [ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size] forKey: of_file_attribute_key_size]; setTypeAttribute(ret, &s); - [ret setObject: [NSNumber numberWithUInt16: s.st_mode & 07777] + [ret setObject: [NSNumber numberWithUnsignedLong: s.st_mode] forKey: of_file_attribute_key_posix_permissions]; setOwnerAndGroupAttributes(ret, &s); setDateAttributes(ret, &s); @@ -758,11 +758,11 @@ - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL attributes: (of_file_attributes_t)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS - uint16_t mode = permissions.uInt16Value & 0777; + mode_t mode = (mode_t)permissions.unsignedLongValue; OFString *path = URL.fileSystemRepresentation; int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) Index: src/OFGZIPStream.h ================================================================== --- src/OFGZIPStream.h +++ src/OFGZIPStream.h @@ -20,11 +20,11 @@ @class OFInflateStream; OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFGZIPStream OFGZIPStream.h ObjFW/OFGZIPStream.h * * @brief A class that handles GZIP compression and decompression transparently * for an underlying stream. */ @@ -80,28 +80,28 @@ OFDate *_Nullable _modificationDate; uint16_t _extraLength; uint32_t _CRC32, _uncompressedSize; } -/*! +/** * @brief The operating system on which the data was compressed. * * This property is only guaranteed to be available once @ref atEndOfStream is * true. */ @property (readonly, nonatomic) enum of_gzip_stream_operating_system operatingSystemMadeOn; -/*! +/** * @brief The modification date of the original file. * * This property is only guaranteed to be available once @ref atEndOfStream is * true. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFDate *modificationDate; -/*! +/** * @brief Creates a new OFGZIPStream with the specified underlying stream. * * @param stream The underlying stream for the OFGZIPStream * @param mode The mode for the OFGZIPStream. Valid modes are "r" for reading * and "w" for writing. @@ -110,11 +110,11 @@ + (instancetype)streamWithStream: (OFStream *)stream mode: (OFString *)mode; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFGZIPStream with the specified * underlying stream. * * @param stream The underlying stream for the OFGZIPStream * @param mode The mode for the OFGZIPStream. Valid modes are "r" for reading Index: src/OFHMAC.h ================================================================== --- src/OFHMAC.h +++ src/OFHMAC.h @@ -18,11 +18,11 @@ #import "OFObject.h" #import "OFCryptoHash.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFHMAC OFHMAC.h ObjFW/OFHMAC.h * * @brief A class which provides methods to calculate an HMAC. */ OF_SUBCLASSING_RESTRICTED @@ -33,35 +33,35 @@ id _Nullable _outerHash, _innerHash; id _Nullable _outerHashCopy, _innerHashCopy; bool _calculated; } -/*! +/** * @brief The class for the cryptographic hash used by the HMAC. */ @property (readonly, nonatomic) Class hashClass; -/*! +/** * @brief Whether data may be stored in swappable memory. */ @property (readonly, nonatomic) bool allowsSwappableMemory; -/*! +/** * @brief A buffer containing the HMAC. * * The size of the buffer depends on the hash used. The buffer is part of the * receiver's memory pool. */ @property (readonly, nonatomic) const unsigned char *digest OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The size of the digest. */ @property (readonly, nonatomic) size_t digestSize; -/*! +/** * @brief Returns a new OFHMAC with the specified hashing algorithm. * * @param hashClass The class of the hashing algorithm * @param allowsSwappableMemory Whether data may be stored in swappable memory * @return A new, autoreleased OFHMAC @@ -69,11 +69,11 @@ + (instancetype)HMACWithHashClass: (Class )hashClass allowsSwappableMemory: (bool)allowsSwappableMemory; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initialized an already allocated OFHMAC with the specified hashing * algorithm. * * @param hashClass The class of the hashing algorithm * @param allowsSwappableMemory Whether data may be stored in swappable memory @@ -81,11 +81,11 @@ */ - (instancetype)initWithHashClass: (Class )hashClass allowsSwappableMemory: (bool)allowsSwappableMemory OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Sets the key for the HMAC. * * @note This resets the HMAC! * * @warning This invalidates any pointer previously returned by @ref digest. If @@ -96,20 +96,20 @@ * @param length The length of the key for the HMAC */ - (void)setKey: (const void *)key length: (size_t)length; -/*! +/** * @brief Adds a buffer to the HMAC to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; -/*! +/** * @brief Resets the HMAC so that it can be calculated for a new message. * * @note This does not reset the key so that a new HMAC with the same key can * be calculated efficiently. If you want to reset both, use * @ref setKey:length:. @@ -118,15 +118,15 @@ * you are still interested in the previous digest, you need to memcpy * it yourself before calling @ref reset! */ - (void)reset; -/*! +/** * @brief This is like @ref reset, but also zeroes the hashed key and all state. * * @warning After calling this, you *must* set a new key before reusing the * HMAC! */ - (void)zero; @end OF_ASSUME_NONNULL_END Index: src/OFHTTPClient.h ================================================================== --- src/OFHTTPClient.h +++ src/OFHTTPClient.h @@ -29,17 +29,17 @@ @class OFHTTPResponse; @class OFStream; @class OFTCPSocket; @class OFURL; -/*! +/** * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A delegate for OFHTTPClient. */ @protocol OFHTTPClientDelegate -/*! +/** * @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 @@ -46,11 +46,11 @@ */ - (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 @@ -59,11 +59,11 @@ - (void)client: (OFHTTPClient *)client didFailWithException: (id)exception request: (OFHTTPRequest *)request; @optional -/*! +/** * @brief A callback which is called when an OFHTTPClient creates a socket. * * This is useful if the connection is using HTTPS and the server requires a * client certificate. This callback can then be used to tell the TLS socket * about the certificate. Another use case is to tell the socket about a SOCKS5 @@ -75,11 +75,11 @@ */ - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)socket request: (OFHTTPRequest *)request; -/*! +/** * @brief A callback which is called when an OFHTTPClient wants to send the * body for a request. * * @param client The OFHTTPClient that wants to send the body * @param requestBody A stream into which the body of the request should be @@ -88,11 +88,11 @@ */ - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)requestBody request: (OFHTTPRequest *)request; -/*! +/** * @brief A callback which is called when an OFHTTPClient received headers. * * @param client The OFHTTPClient which received the headers * @param headers The headers received * @param statusCode The status code received @@ -102,11 +102,11 @@ - (void)client: (OFHTTPClient *)client didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers statusCode: (int)statusCode request: (OFHTTPRequest *)request; -/*! +/** * @brief A callback which is called when an OFHTTPClient wants to follow a * redirect. * * If you want to get the headers and data for each redirect, set the number of * redirects to 0 and perform a new OFHTTPClient for each redirect. However, @@ -133,11 +133,11 @@ statusCode: (int)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response; @end -/*! +/** * @class OFHTTPClient OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A class for performing HTTP requests. */ OF_SUBCLASSING_RESTRICTED @@ -152,29 +152,29 @@ OFURL *_Nullable _lastURL; bool _lastWasHEAD; OFHTTPResponse *_Nullable _lastResponse; } -/*! +/** * @brief The delegate of the HTTP request. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) OFObject *delegate; -/*! +/** * @brief Whether the HTTP client allows redirects from HTTPS to HTTP. */ @property (nonatomic) bool allowsInsecureRedirects; -/*! +/** * @brief Creates a new OFHTTPClient. * * @return A new, autoreleased OFHTTPClient */ + (instancetype)client; -/*! +/** * @brief Synchronously performs the specified HTTP request. * * @note You must not change the delegate while a synchronous request is * running! If you want to change the delegate during the request, * perform an asynchronous request instead! @@ -182,11 +182,11 @@ * @param request The request to perform * @return The OFHTTPResponse for the request */ - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request; -/*! +/** * @brief Synchronously performs the specified HTTP request. * * @note You must not change the delegate while a synchronous request is * running! If you want to change the delegate during the request, * perform an asynchronous request instead! @@ -198,18 +198,18 @@ * @return The OFHTTPResponse for the request */ - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; -/*! +/** * @brief Asynchronously performs the specified HTTP request. * * @param request The request to perform */ - (void)asyncPerformRequest: (OFHTTPRequest *)request; -/*! +/** * @brief Asynchronously performs the specified HTTP request. * * @param request The request to perform * @param redirects The maximum number of redirects after which no further * attempt is done to follow the redirect, but instead the @@ -216,12 +216,12 @@ * redirect is treated as an OFHTTPResponse */ - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; -/*! +/** * @brief Closes connections that are still open due to keep-alive. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -77,11 +77,11 @@ @interface OFHTTPClientRequestBodyStream: OFStream { OFHTTPClientRequestHandler *_handler; OFTCPSocket *_socket; bool _chunked; - uintmax_t _toWrite; + unsigned long long _toWrite; bool _atEndOfStream; } - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler socket: (OFTCPSocket *)sock; @@ -91,11 +91,11 @@ @interface OFHTTPClientResponse: OFHTTPResponse { OFTCPSocket *_socket; bool _hasContentLength, _chunked, _keepAlive; bool _atEndOfStream, _setAtEndOfStream; - intmax_t _toRead; + long long _toRead; } @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock; @@ -443,10 +443,12 @@ } } - (bool)handleFirstLine: (OFString *)line { + long long status; + /* * It's possible that the write succeeds on a connection that is * keep-alive, but the connection has already been closed by the remote * end due to a timeout. In this case, we need to reconnect. */ @@ -462,11 +464,16 @@ _version = [[line substringWithRange: of_range(5, 3)] copy]; if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"]) @throw [OFUnsupportedVersionException exceptionWithVersion: _version]; - _status = (int)[line substringWithRange: of_range(9, 3)].decimalValue; + status = [line substringWithRange: of_range(9, 3)].longLongValue; + + if (status < 0 || status > 599) + @throw [OFInvalidServerReplyException exception]; + + _status = (int)status; return true; } - (bool)handleServerHeader: (OFString *)line @@ -711,11 +718,11 @@ port = 80; } URLPort = URL.port; if (URLPort != nil) - port = URLPort.uInt16Value; + port = URLPort.unsignedShortValue; sock.delegate = self; [sock asyncConnectToHost: URL.host port: port]; } @catch (id e) { @@ -730,11 +737,10 @@ { self = [super init]; @try { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; - intmax_t contentLength; OFString *transferEncoding, *contentLengthString; _handler = [handler retain]; _socket = [sock retain]; @@ -747,15 +753,11 @@ if (contentLengthString != nil) { if (_chunked || contentLengthString.length == 0) @throw [OFInvalidArgumentException exception]; - contentLength = contentLengthString.decimalValue; - if (contentLength < 0) - @throw [OFOutOfRangeException exception]; - - _toWrite = contentLength; + _toWrite = contentLengthString.unsignedLongLongValue; } else if (!_chunked) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; @@ -893,15 +895,17 @@ @throw [OFInvalidServerReplyException exception]; _hasContentLength = true; @try { - _toRead = contentLength.decimalValue; + unsigned long long toRead = + contentLength.unsignedLongLongValue; - if (_toRead < 0) - @throw [OFInvalidServerReplyException - exception]; + if (toRead > LLONG_MAX) + @throw [OFOutOfRangeException exception]; + + _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } } } @@ -924,11 +928,11 @@ /* Content-Length */ if (!_chunked) { size_t ret; - if (length > (uintmax_t)_toRead) + if (length > (unsigned long long)_toRead) length = (size_t)_toRead; ret = [_socket readIntoBuffer: buffer length: length]; @@ -979,11 +983,11 @@ if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { - if (length > (uintmax_t)_toRead) + if (length > (unsigned long long)_toRead) length = (size_t)_toRead; length = [_socket readIntoBuffer: buffer length: length]; @@ -1024,12 +1028,17 @@ @throw [OFInvalidServerReplyException exception]; } @try { - if ((_toRead = line.hexadecimalValue) < 0) + unsigned long long toRead = + [line unsignedLongLongValueWithBase: 16]; + + if (toRead > LLONG_MAX) @throw [OFOutOfRangeException exception]; + + _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } if (_toRead == 0) { Index: src/OFHTTPCookie.h ================================================================== --- src/OFHTTPCookie.h +++ src/OFHTTPCookie.h @@ -24,11 +24,11 @@ @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFURL; -/*! +/** * @class OFHTTPCookie OFHTTPCookie.h ObjFW/OFHTTPCookie.h * * @brief A class for storing and manipulating HTTP cookies. */ @interface OFHTTPCookie: OFObject @@ -35,55 +35,55 @@ { OFString *_name, *_value, *_domain, *_path; OFDate *_Nullable _expires; bool _secure, _HTTPOnly; OFMutableArray OF_GENERIC(OFString *) *_extensions; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFHTTPCookie, 4) } -/*! +/** * @brief The name of the cookie. */ @property (copy, nonatomic) OFString *name; -/*! +/** * @brief The value of the cookie. */ @property (copy, nonatomic) OFString *value; -/*! +/** * @brief The domain for the cookie. */ @property (copy, nonatomic) OFString *domain; -/*! +/** * @brief The path for the cookie. */ @property (copy, nonatomic) OFString *path; -/*! +/** * @brief The date when the cookie expires. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFDate *expires; -/*! +/** * @brief Whether the cookie is only to be used with HTTPS. */ @property (nonatomic, getter=isSecure) bool secure; -/*! +/** * @brief Whether the cookie is only to be accessed through HTTP. */ @property (nonatomic, getter=isHTTPOnly) bool HTTPOnly; -/*! +/** * @brief An array of other attributes. */ @property (readonly, nonatomic) OFMutableArray OF_GENERIC(OFString *) *extensions; -/*! +/** * @brief Parses the specified response header fields for the specified URL and * returns an array of cookies. * * @param headerFields The response header fields to parse * @param URL The URL for the response header fields to parse @@ -91,20 +91,20 @@ */ + (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesWithResponseHeaderFields: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields forURL: (OFURL *)URL; -/*! +/** * @brief Returns the request header fields for the specified cookies. * * @param cookies The cookies to return the request header fields for * @return The request header fields for the specified cookies */ + (OFDictionary *)requestHeaderFieldsWithCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies; -/*! +/** * @brief Create a new cookie with the specified name and value. * * @param name The name of the cookie * @param value The value of the cookie * @param domain The domain for the cookie @@ -114,11 +114,11 @@ value: (OFString *)value domain: (OFString *)domain; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated new cookie with the specified name * and value. * * @param name The name of the cookie * @param value The value of the cookie Index: src/OFHTTPCookie.m ================================================================== --- src/OFHTTPCookie.m +++ src/OFHTTPCookie.m @@ -36,11 +36,11 @@ dateWithDateString: value format: @"%a, %d %b %Y %H:%M:%S %z"]; cookie.expires = date; } else if ([lowercaseName isEqual: @"max-age"]) { OFDate *date = [OFDate dateWithTimeIntervalSinceNow: - value.decimalValue]; + value.unsignedLongLongValue]; cookie.expires = date; } else if ([lowercaseName isEqual: @"domain"]) cookie.domain = value; else if ([lowercaseName isEqual: @"path"]) cookie.path = value; Index: src/OFHTTPCookieManager.h ================================================================== --- src/OFHTTPCookieManager.h +++ src/OFHTTPCookieManager.h @@ -22,11 +22,11 @@ @class OFArray OF_GENERIC(ObjectType); @class OFHTTPCookie; @class OFMutableArray OF_GENERIC(ObjectType); @class OFURL; -/*! +/** * @class OFHTTPCookieManager OFHTTPCookieManager.h ObjFW/OFHTTPCookieManager.h * * @brief A class for managing cookies for multiple domains. */ OF_SUBCLASSING_RESTRICTED @@ -33,23 +33,23 @@ @interface OFHTTPCookieManager: OFObject { OFMutableArray OF_GENERIC(OFHTTPCookie *) *_cookies; } -/*! +/** * @brief All cookies known to the cookie manager. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFHTTPCookie *) *cookies; -/*! +/** * @brief Create a new cookie manager. * * @return A new, autoreleased OFHTTPCookieManager */ + (instancetype)manager; -/*! +/** * @brief Adds the specified cookie for the specified URL. * * @warning This modifies the cookie (e.g. it sets the domain if it is unset)! * If you do not want this, pass a copy! * @@ -57,11 +57,11 @@ * @param URL The URL for which the cookie should be added */ - (void)addCookie: (OFHTTPCookie *)cookie forURL: (OFURL *)URL; -/*! +/** * @brief Adds the specified cookies for the specified URL. * * @warning This modifies the cookies (e.g. it sets the domain if it is unset)! * If you do not want this, pass copies! * @@ -69,20 +69,20 @@ * @param URL The URL for which the cookies should be added */ - (void)addCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies forURL: (OFURL *)URL; -/*! +/** * @brief Returns the cookies for the specified URL. * * @param URL The URL for which the cookies should be returned * @return The cookies for the specified URL */ - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesForURL: (OFURL *)URL; -/*! +/** * @brief Purges all expired cookies. */ - (void)purgeExpiredCookies; @end OF_ASSUME_NONNULL_END Index: src/OFHTTPRequest.h ================================================================== --- src/OFHTTPRequest.h +++ src/OFHTTPRequest.h @@ -25,50 +25,50 @@ @class OFURL; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFData; @class OFString; -/*! @file */ +/** @file */ -/*! +/** * @brief The type of an HTTP request. */ typedef enum { - /*! OPTIONS */ + /** OPTIONS */ OF_HTTP_REQUEST_METHOD_OPTIONS, - /*! GET */ + /** GET */ OF_HTTP_REQUEST_METHOD_GET, - /*! HEAD */ + /** HEAD */ OF_HTTP_REQUEST_METHOD_HEAD, - /*! POST */ + /** POST */ OF_HTTP_REQUEST_METHOD_POST, - /*! PUT */ + /** PUT */ OF_HTTP_REQUEST_METHOD_PUT, - /*! DELETE */ + /** DELETE */ OF_HTTP_REQUEST_METHOD_DELETE, - /*! TRACE */ + /** TRACE */ OF_HTTP_REQUEST_METHOD_TRACE, - /*! CONNECT */ + /** CONNECT */ OF_HTTP_REQUEST_METHOD_CONNECT } of_http_request_method_t; -/*! +/** * @struct of_http_request_protocol_version_t \ * OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief The HTTP version of the HTTP request. */ struct OF_BOXABLE of_http_request_protocol_version_t { - /*! The major of the HTTP version */ + /** The major of the HTTP version */ uint8_t major; - /*! The minor of the HTTP version */ + /** The minor of the HTTP version */ uint8_t minor; }; typedef struct of_http_request_protocol_version_t of_http_request_protocol_version_t; -/*! +/** * @class OFHTTPRequest OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief A class for storing HTTP requests. */ @interface OFHTTPRequest: OFObject @@ -76,63 +76,64 @@ OFURL *_URL; of_http_request_method_t _method; of_http_request_protocol_version_t _protocolVersion; OFDictionary OF_GENERIC(OFString *, OFString *) *_Nullable _headers; of_socket_address_t _remoteAddress; - OF_RESERVE_IVARS(4) + bool _hasRemoteAddress; + OF_RESERVE_IVARS(OFHTTPRequest, 4) } -/*! +/** * @brief The URL of the HTTP request. */ @property (copy, nonatomic) OFURL *URL; -/*! +/** * @brief The protocol version of the HTTP request. */ @property (nonatomic) of_http_request_protocol_version_t protocolVersion; -/*! +/** * @brief The protocol version of the HTTP request as a string. */ @property (copy, nonatomic) OFString *protocolVersionString; -/*! +/** * @brief The request method of the HTTP request. */ @property (nonatomic) of_http_request_method_t method; -/*! +/** * @brief The headers for the HTTP request. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *headers; -/*! +/** * @brief The remote address from which the request originates. * * @note The setter creates a copy of the remote address. */ @property OF_NULLABLE_PROPERTY (nonatomic) const of_socket_address_t *remoteAddress; -/*! +/** * @brief Creates a new OFHTTPRequest. * * @return A new, autoreleased OFHTTPRequest */ + (instancetype)request; -/*! +/** * @brief Creates a new OFHTTPRequest with the specified URL. * * @param URL The URL for the request * @return A new, autoreleased OFHTTPRequest */ + (instancetype)requestWithURL: (OFURL *)URL; -/*! +/** * @brief Initializes an already allocated OFHTTPRequest with the specified URL. * * @param URL The URL for the request * @return An initialized OFHTTPRequest */ @@ -140,20 +141,20 @@ @end #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief Returns a C string describing the specified request method. * * @param method The request method which should be described as a C string * @return A C string describing the specified request method */ extern const char *_Nullable of_http_request_method_to_string( of_http_request_method_t method); -/*! +/** * @brief Returns the request method for the specified string. * * @param string The string for which the request method should be returned * @return The request method for the specified string */ Index: src/OFHTTPRequest.m ================================================================== --- src/OFHTTPRequest.m +++ src/OFHTTPRequest.m @@ -125,16 +125,22 @@ [super dealloc]; } - (void)setRemoteAddress: (const of_socket_address_t *)remoteAddress { - _remoteAddress = *remoteAddress; + _hasRemoteAddress = (remoteAddress != NULL); + + if (_hasRemoteAddress) + _remoteAddress = *remoteAddress; } - (const of_socket_address_t *)remoteAddress { - return &_remoteAddress; + if (_hasRemoteAddress) + return &_remoteAddress; + + return NULL; } - (id)copy { OFHTTPRequest *copy = [[OFHTTPRequest alloc] init]; @@ -142,11 +148,11 @@ @try { copy->_method = _method; copy->_protocolVersion = _protocolVersion; copy.URL = _URL; copy.headers = _headers; - copy.remoteAddress = &_remoteAddress; + copy.remoteAddress = self.remoteAddress; } @catch (id e) { [copy release]; @throw e; } @@ -167,12 +173,15 @@ if (request->_method != _method || request->_protocolVersion.major != _protocolVersion.major || request->_protocolVersion.minor != _protocolVersion.minor || ![request->_URL isEqual: _URL] || - ![request->_headers isEqual: _headers] || - !of_socket_address_equal(&request->_remoteAddress, &_remoteAddress)) + ![request->_headers isEqual: _headers]) + return false; + + if (request.remoteAddress != self.remoteAddress && + !of_socket_address_equal(request.remoteAddress, self.remoteAddress)) return false; return true; } @@ -185,11 +194,12 @@ OF_HASH_ADD(hash, _method); OF_HASH_ADD(hash, _protocolVersion.major); OF_HASH_ADD(hash, _protocolVersion.minor); OF_HASH_ADD_HASH(hash, _URL.hash); OF_HASH_ADD_HASH(hash, _headers.hash); - OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_remoteAddress)); + if (_hasRemoteAddress) + OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_remoteAddress)); OF_HASH_FINALIZE(hash); return hash; } @@ -212,20 +222,20 @@ - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; - intmax_t major, minor; + unsigned long long major, minor; of_http_request_protocol_version_t protocolVersion; if (components.count != 2) @throw [OFInvalidFormatException exception]; - major = [components.firstObject decimalValue]; - minor = [components.lastObject decimalValue]; + major = [components.firstObject unsignedLongLongValue]; + minor = [components.lastObject unsignedLongLongValue]; - if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX) + if (major > UINT8_MAX || minor > UINT8_MAX) @throw [OFOutOfRangeException exception]; protocolVersion.major = (uint8_t)major; protocolVersion.minor = (uint8_t)minor; @@ -243,25 +253,30 @@ - (OFString *)description { void *pool = objc_autoreleasePoolPush(); const char *method = of_http_request_method_to_string(_method); - OFString *indentedHeaders, *ret; + OFString *indentedHeaders, *remoteAddress, *ret; indentedHeaders = [_headers.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; + + if (_hasRemoteAddress) + remoteAddress = + of_socket_address_ip_string(&_remoteAddress, NULL); + else + remoteAddress = nil; ret = [[OFString alloc] initWithFormat: @"<%@:\n\tURL = %@\n" @"\tMethod = %s\n" @"\tHeaders = %@\n" @"\tRemote address = %@\n" @">", - self.class, _URL, method, indentedHeaders, - of_socket_address_ip_string(&_remoteAddress, NULL)]; + self.class, _URL, method, indentedHeaders, remoteAddress]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end Index: src/OFHTTPResponse.h ================================================================== --- src/OFHTTPResponse.h +++ src/OFHTTPResponse.h @@ -21,50 +21,50 @@ OF_ASSUME_NONNULL_BEGIN @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFArray OF_GENERIC(ObjectType); -/*! +/** * @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h * * @brief A class for representing an HTTP request reply as a stream. */ @interface OFHTTPResponse: OFStream { of_http_request_protocol_version_t _protocolVersion; short _statusCode; OFDictionary OF_GENERIC(OFString *, OFString *) *_headers; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFHTTPResponse, 4) } -/*! +/** * @brief The protocol version of the HTTP request reply. */ @property (nonatomic) of_http_request_protocol_version_t protocolVersion; -/*! +/** * @brief The protocol version of the HTTP request reply as a string. */ @property (copy, nonatomic) OFString *protocolVersionString; -/*! +/** * @brief The status code of the reply to the HTTP request. */ @property (nonatomic) short statusCode; -/*! +/** * @brief The headers of the reply to the HTTP request. */ @property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *headers; -/*! +/** * @brief The reply as a string, trying to detect the encoding. */ @property (readonly, nonatomic) OFString *string; -/*! +/** * @brief Returns the reply as a string, trying to detect the encoding and * falling back to the specified encoding if not detectable. * * @return The reply as a string */ @@ -72,11 +72,11 @@ @end #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief Returns a description string for the specified HTTP status code. * * @param code The HTTP status code to return a description string for * @return A description string for the specified HTTP status code */ Index: src/OFHTTPResponse.m ================================================================== --- src/OFHTTPResponse.m +++ src/OFHTTPResponse.m @@ -269,20 +269,20 @@ - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; - intmax_t major, minor; + unsigned long long major, minor; of_http_request_protocol_version_t protocolVersion; if (components.count != 2) @throw [OFInvalidFormatException exception]; - major = [components.firstObject decimalValue]; - minor = [components.lastObject decimalValue]; + major = [components.firstObject unsignedLongLongValue]; + minor = [components.lastObject unsignedLongLongValue]; - if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX) + if (major > UINT8_MAX || minor > UINT8_MAX) @throw [OFOutOfRangeException exception]; protocolVersion.major = (uint8_t)major; protocolVersion.minor = (uint8_t)minor; @@ -304,11 +304,11 @@ } - (OFString *)stringWithEncoding: (of_string_encoding_t)encoding { void *pool = objc_autoreleasePoolPush(); - OFString *contentType, *contentLength, *ret; + OFString *contentType, *contentLengthString, *ret; OFData *data; if (encoding == OF_STRING_ENCODING_AUTODETECT && (contentType = [_headers objectForKey: @"Content-Type"]) != nil) encoding = encodingForContentType(contentType); @@ -316,13 +316,21 @@ if (encoding == OF_STRING_ENCODING_AUTODETECT) encoding = OF_STRING_ENCODING_UTF_8; data = [self readDataUntilEndOfStream]; - if ((contentLength = [_headers objectForKey: @"Content-Length"]) != nil) - if (data.count != (size_t)contentLength.decimalValue) + contentLengthString = [_headers objectForKey: @"Content-Length"]; + if (contentLengthString != nil) { + unsigned long long contentLength = + contentLengthString.unsignedLongLongValue; + + if (contentLength > SIZE_MAX) + @throw [OFOutOfRangeException exception]; + + if (data.count != (size_t)contentLength) @throw [OFTruncatedDataException exception]; + } ret = [[OFString alloc] initWithCString: (char *)data.items encoding: encoding length: data.count]; Index: src/OFHTTPServer.h ================================================================== --- src/OFHTTPServer.h +++ src/OFHTTPServer.h @@ -28,17 +28,17 @@ @class OFHTTPResponse; @class OFHTTPServer; @class OFStream; @class OFTCPSocket; -/*! +/** * @protocol OFHTTPServerDelegate OFHTTPServer.h ObjFW/OFHTTPServer.h * * @brief A delegate for OFHTTPServer. */ @protocol OFHTTPServerDelegate -/*! +/** * @brief This method is called when the HTTP server received a request from a * client. * * @param server The HTTP server which received the request * @param request The request the HTTP server received @@ -49,11 +49,11 @@ didReceiveRequest: (OFHTTPRequest *)request requestBody: (nullable OFStream *)requestBody response: (OFHTTPResponse *)response; @optional -/*! +/** * @brief This method is called when the HTTP server's listening socket * encountered an exception. * * @param server The HTTP server which encountered an exception * @param exception The exception which occurred on the HTTP server's listening @@ -63,11 +63,11 @@ * connections again by calling @ref OFHTTPServer::start again. */ - (bool)server: (OFHTTPServer *)server didReceiveExceptionOnListeningSocket: (id)exception; -/*! +/** * @brief This method is called when a client socket encountered an exception. * * This can happen when the OFHTTPServer tries to properly close the * connection. If no headers have been sent yet, it will send headers, and if * chunked transfer encoding was used, it will send a chunk of size 0. However, @@ -83,11 +83,11 @@ didReceiveExceptionForResponse: (OFHTTPResponse *)response request: (OFHTTPRequest *)request exception: (id)exception; @end -/*! +/** * @class OFHTTPServer OFHTTPServer.h ObjFW/OFHTTPServer.h * * @brief A class for creating a simple HTTP server inside of applications. */ OF_SUBCLASSING_RESTRICTED @@ -105,51 +105,51 @@ size_t _numberOfThreads, _nextThreadIndex; OFArray *_threadPool; #endif } -/*! +/** * @brief The host on which the HTTP server will listen. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *host; -/*! +/** * @brief The port on which the HTTP server will listen. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property (nonatomic) uint16_t port; -/*! +/** * @brief Whether the HTTP server uses TLS. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property (nonatomic) bool usesTLS; -/*! +/** * @brief The path to the X.509 certificate file to use for TLS. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *certificateFile; -/*! +/** * @brief The path to the PKCS#8 private key file to use for TLS. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *privateKeyFile; -/*! +/** * @brief The passphrase to decrypt the PKCS#8 private key file for TLS. * * @warning You have to ensure that this is in secure memory protected from * swapping! This is also the reason why this is not an OFString. * @@ -157,18 +157,18 @@ * @ref OFAlreadyConnectedException. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) const char *privateKeyPassphrase; -/*! +/** * @brief The delegate for the HTTP server. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; #ifdef OF_HAVE_THREADS -/*! +/** * @brief The number of threads the OFHTTPServer should use. * * If this is larger than 1 (the default), one thread will be used to accept * incoming connections and all others will be used to handle connections. * @@ -178,34 +178,34 @@ * @ref OFAlreadyConnectedException. */ @property (nonatomic) size_t numberOfThreads; #endif -/*! +/** * @brief The server name the server presents to clients. * * Setting it to `nil` means no `Server` header will be sent, unless one is * specified in the response headers. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *name; -/*! +/** * @brief Creates a new HTTP server. * * @return A new HTTP server */ + (instancetype)server; -/*! +/** * @brief Starts the HTTP server in the current thread's run loop. */ - (void)start; -/*! +/** * @brief Stops the HTTP server, meaning it will not accept any new incoming * connections, but still handle existing connections until they are * finished or timed out. */ - (void)stop; @end OF_ASSUME_NONNULL_END Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -103,17 +103,17 @@ OF_DIRECT_MEMBERS @interface OFHTTPServerRequestBodyStream: OFStream { OFStreamSocket *_socket; bool _chunked; - intmax_t _toRead; + long long _toRead; bool _atEndOfStream, _setAtEndOfStream; } - (instancetype)initWithSocket: (OFStreamSocket *)sock chunked: (bool)chunked - contentLength: (uintmax_t)contentLength; + contentLength: (unsigned long long)contentLength; @end #ifdef OF_HAVE_THREADS OF_DIRECT_MEMBERS @interface OFHTTPServerThread: OFThread @@ -413,25 +413,22 @@ if (line.length == 0) { bool chunked = [[_headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; OFString *contentLengthString = [_headers objectForKey: @"Content-Length"]; - intmax_t contentLength = 0; + unsigned long long contentLength = 0; if (contentLengthString != nil) { if (chunked || contentLengthString.length == 0) return [self sendErrorAndClose: 400]; @try { contentLength = - contentLengthString.decimalValue; + contentLengthString.unsignedLongLongValue; } @catch (OFInvalidFormatException *e) { return [self sendErrorAndClose: 400]; } - - if (contentLength < 0) - return [self sendErrorAndClose: 400]; } if (chunked || contentLengthString != nil) { [_requestBody release]; _requestBody = nil; @@ -480,12 +477,13 @@ of_range(0, pos)] retain]; @try { of_range_t range = of_range(pos + 1, value.length - pos - 1); - intmax_t portTmp = [value - substringWithRange: range].decimalValue; + unsigned long long portTmp = + [value substringWithRange: range] + .unsignedLongLongValue; if (portTmp < 1 || portTmp > UINT16_MAX) return [self sendErrorAndClose: 400]; _port = (uint16_t)portTmp; @@ -543,11 +541,11 @@ URL = [OFMutableURL URL]; URL.scheme = @"http"; URL.host = _host; if (_port != 80) - URL.port = [OFNumber numberWithUInt16: _port]; + URL.port = [OFNumber numberWithUnsignedShort: _port]; if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) { OFString *path, *query; path = [_path substringWithRange: of_range(0, pos)]; @@ -583,18 +581,21 @@ @end @implementation OFHTTPServerRequestBodyStream - (instancetype)initWithSocket: (OFStreamSocket *)sock chunked: (bool)chunked - contentLength: (uintmax_t)contentLength + contentLength: (unsigned long long)contentLength { self = [super init]; @try { + if (contentLength > LLONG_MAX) + @throw [OFOutOfRangeException exception]; + _socket = [sock retain]; _chunked = chunked; - _toRead = contentLength; + _toRead = (long long)contentLength; if (_chunked && _toRead > 0) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @@ -631,11 +632,11 @@ /* Content-Length */ if (!_chunked) { size_t ret; - if (length > (uintmax_t)_toRead) + if (length > (unsigned long long)_toRead) length = (size_t)_toRead; ret = [_socket readIntoBuffer: buffer length: length]; @@ -680,11 +681,11 @@ if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { - if (length > (uintmax_t)_toRead) + if (length > (unsigned long long)_toRead) length = (size_t)_toRead; length = [_socket readIntoBuffer: buffer length: length]; @@ -696,10 +697,11 @@ return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; of_range_t range; + unsigned long long toRead; @try { line = [_socket tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidFormatException exception]; @@ -723,12 +725,14 @@ @throw [OFTruncatedDataException exception]; else @throw [OFInvalidFormatException exception]; } - if ((_toRead = line.hexadecimalValue) < 0) + toRead = [line unsignedLongLongValueWithBase: 16]; + if (toRead > LLONG_MAX) @throw [OFOutOfRangeException exception]; + _toRead = (long long)toRead; if (_toRead == 0) { _setAtEndOfStream = true; _toRead = -2; } Index: src/OFHostAddressResolver.m ================================================================== --- src/OFHostAddressResolver.m +++ src/OFHostAddressResolver.m @@ -207,11 +207,11 @@ return; } for (OF_KINDOF(OFDNSResourceRecord *) record in [response.answerRecords objectForKey: query.domainName]) { - const of_socket_address_t *address; + const of_socket_address_t *address = NULL; OFDNSQuery *CNAMEQuery; if ([record DNSClass] != OF_DNS_CLASS_IN) continue; Index: src/OFINICategory.h ================================================================== --- src/OFINICategory.h +++ src/OFINICategory.h @@ -21,11 +21,11 @@ @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFString; -/*! +/** * @class OFINICategory OFINICategory.h ObjFW/OFINICategory.h * * @brief A class for representing a category of an INI file. */ OF_SUBCLASSING_RESTRICTED @@ -33,18 +33,18 @@ { OFString *_name; OFMutableArray *_lines; } -/*! +/** * @brief The name of the INI category */ @property (copy, nonatomic) OFString *name; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Returns the string value for the specified key, or `nil` if it does * not exist. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is returned. @@ -52,11 +52,11 @@ * @param key The key for which the string value should be returned * @return The string value for the specified key, or `nil` if it does not exist */ - (nullable OFString *)stringForKey: (OFString *)key; -/*! +/** * @brief Returns the string value for the specified key or the specified * default value if it does not exist. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is returned. @@ -67,11 +67,11 @@ * value if it does not exist */ - (nullable OFString *)stringForKey: (OFString *)key defaultValue: (nullable OFString *)defaultValue; -/*! +/** * @brief Returns the integer value for the specified key or the specified * default value if it does not exist. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is returned. @@ -79,14 +79,14 @@ * @param key The key for which the integer value should be returned * @param defaultValue The value to return if the key does not exist * @return The integer value for the specified key or the specified default * value if it does not exist */ -- (intmax_t)integerForKey: (OFString *)key - defaultValue: (intmax_t)defaultValue; +- (long long)integerForKey: (OFString *)key + defaultValue: (long long)defaultValue; -/*! +/** * @brief Returns the bool value for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is returned. @@ -97,11 +97,11 @@ * if it does not exist */ - (bool)boolForKey: (OFString *)key defaultValue: (bool)defaultValue; -/*! +/** * @brief Returns the float value for the specified key or the specified * default value if it does not exist. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is returned. @@ -112,11 +112,11 @@ * if it does not exist */ - (float)floatForKey: (OFString *)key defaultValue: (float)defaultValue; -/*! +/** * @brief Returns the double value for the specified key or the specified * default value if it does not exist. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is returned. @@ -127,11 +127,11 @@ * value if it does not exist */ - (double)doubleForKey: (OFString *)key defaultValue: (double)defaultValue; -/*! +/** * @brief Returns an array of string values for the specified multi-key, or an * empty array if the key does not exist. * * A multi-key is a key which exists several times in the same category. Each * occurrence of the key/value pair adds the respective value to the array. @@ -140,11 +140,11 @@ * @return The array for the specified key, or an empty array if it does not * exist */ - (OFArray OF_GENERIC(OFString *) *)arrayForKey: (OFString *)key; -/*! +/** * @brief Sets the value of the specified key to the specified string. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is changed. * @@ -152,23 +152,23 @@ * @param key The key for which the new value should be set */ - (void)setString: (OFString *)string forKey: (OFString *)key; -/*! +/** * @brief Sets the value of the specified key to the specified integer. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is changed. * * @param integer The integer to which the value of the key should be set * @param key The key for which the new value should be set */ -- (void)setInteger: (intmax_t)integer +- (void)setInteger: (long long)integer forKey: (OFString *)key; -/*! +/** * @brief Sets the value of the specified key to the specified bool. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is changed. * @@ -176,11 +176,11 @@ * @param key The key for which the new value should be set */ - (void)setBool: (bool)bool_ forKey: (OFString *)key; -/*! +/** * @brief Sets the value of the specified key to the specified float. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is changed. * @@ -188,11 +188,11 @@ * @param key The key for which the new value should be set */ - (void)setFloat: (float)float_ forKey: (OFString *)key; -/*! +/** * @brief Sets the value of the specified key to the specified double. * * If the specified key is a multi-key (see @ref arrayForKey:), the value of * the first key/value pair found is changed. * @@ -200,11 +200,11 @@ * @param key The key for which the new value should be set */ - (void)setDouble: (double)double_ forKey: (OFString *)key; -/*! +/** * @brief Sets the specified multi-key to the specified array of strings. * * It replaces the first occurrence of the multi-key with several key/value * pairs and removes all following occurrences. If the multi-key does not exist * yet, it is appended to the section. @@ -215,11 +215,11 @@ * @param key The multi-key for which the new values should be set */ - (void)setArray: (OFArray OF_GENERIC(OFString *) *)array forKey: (OFString *)key; -/*! +/** * @brief Removes the value for the specified key * * If the specified key is a multi-key (see @ref arrayForKey:), all key/value * pairs matching the specified key are removed. * Index: src/OFINICategory.m ================================================================== --- src/OFINICategory.m +++ src/OFINICategory.m @@ -207,24 +207,21 @@ } return defaultValue; } -- (intmax_t)integerForKey: (OFString *)key - defaultValue: (intmax_t)defaultValue +- (long long)integerForKey: (OFString *)key + defaultValue: (long long)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; - intmax_t ret; - - if (value != nil) { - if ([value hasPrefix: @"0x"] || [value hasPrefix: @"$"]) - ret = value.hexadecimalValue; - else - ret = value.decimalValue; - } else + long long ret; + + if (value != nil) + ret = [value longLongValueWithBase: 0]; + else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; @@ -352,16 +349,16 @@ } objc_autoreleasePoolPop(pool); } -- (void)setInteger: (intmax_t)integer +- (void)setInteger: (long long)integer forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); - [self setString: [OFString stringWithFormat: @"%jd", integer] + [self setString: [OFString stringWithFormat: @"%lld", integer] forKey: key]; objc_autoreleasePoolPop(pool); } Index: src/OFINIFile.h ================================================================== --- src/OFINIFile.h +++ src/OFINIFile.h @@ -21,11 +21,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFMutableArray OF_GENERIC(ObjectType); -/*! +/** * @class OFINIFile OFINIFile.h ObjFW/OFINIFile.h * * @brief A class for reading, creating and modifying INI files. */ OF_SUBCLASSING_RESTRICTED @@ -32,20 +32,20 @@ @interface OFINIFile: OFObject { OFMutableArray OF_GENERIC(OFINICategory *) *_categories; } -/*! +/** * @brief Creates a new OFINIFile with the contents of the specified file. * * @param path The path to the file whose contents the OFINIFile should contain * * @return A new, autoreleased OFINIFile with the contents of the specified file */ + (instancetype)fileWithPath: (OFString *)path; -/*! +/** * @brief Creates a new OFINIFile with the contents of the specified file in * the specified encoding. * * @param path The path to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file @@ -55,21 +55,21 @@ + (instancetype)fileWithPath: (OFString *)path encoding: (of_string_encoding_t)encoding; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFINIFile with the contents of the * specified file. * * @param path The path to the file whose contents the OFINIFile should contain * * @return An initialized OFINIFile with the contents of the specified file */ - (instancetype)initWithPath: (OFString *)path; -/*! +/** * @brief Initializes an already allocated OFINIFile with the contents of the * specified file in the specified encoding. * * @param path The path to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file @@ -78,11 +78,11 @@ */ - (instancetype)initWithPath: (OFString *)path encoding: (of_string_encoding_t)encoding OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Returns an @ref OFINICategory for the category with the specified * name. * * @param name The name of the category for which an @ref OFINICategory should * be returned @@ -89,18 +89,18 @@ * * @return An @ref OFINICategory for the category with the specified name */ - (OFINICategory *)categoryForName: (OFString *)name; -/*! +/** * @brief Writes the contents of the OFINIFile to a file. * * @param path The path of the file to write to */ - (void)writeToFile: (OFString *)path; -/*! +/** * @brief Writes the contents of the OFINIFile to a file in the specified * encoding. * * @param path The path of the file to write to * @param encoding The encoding to use Index: src/OFINIFileSettings.m ================================================================== --- src/OFINIFileSettings.m +++ src/OFINIFileSettings.m @@ -86,11 +86,11 @@ forKey: key]; objc_autoreleasePoolPop(pool); } -- (void)setInteger: (intmax_t)integer +- (void)setInteger: (long long)integer forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; @@ -184,16 +184,16 @@ [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } -- (intmax_t)integerForPath: (OFString *)path - defaultValue: (intmax_t)defaultValue +- (long long)integerForPath: (OFString *)path + defaultValue: (long long)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; - intmax_t ret; + long long ret; [self of_getCategory: &category andKey: &key forPath: path]; Index: src/OFIPXSocket.h ================================================================== --- src/OFIPXSocket.h +++ src/OFIPXSocket.h @@ -19,19 +19,19 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @protocol OFIPXSocketDelegate OFIPXSocket.h ObjFW/OFIPXSocket.h * * @brief A delegate for OFIPXSocket. */ @protocol OFIPXSocketDelegate @end -/*! +/** * @class OFIPXSocket OFIPXSocket.h ObjFW/OFIPXSocket.h * * @brief A class which provides methods to create and use IPX sockets. * * Addresses are of type @ref of_socket_address_t. You can use @@ -51,23 +51,23 @@ @interface OFIPXSocket: OFDatagramSocket { #ifndef OF_WINDOWS uint8_t _packetType; #endif - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFIPXSocket, 4) } -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Bind the socket to the specified network, node and port with the * specified packet type. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. Index: src/OFInflate64Stream.h ================================================================== --- src/OFInflate64Stream.h +++ src/OFInflate64Stream.h @@ -20,11 +20,11 @@ OF_ASSUME_NONNULL_BEGIN #define OF_INFLATE64_STREAM_BUFFER_SIZE 4096 -/*! +/** * @class OFInflate64Stream OFInflate64Stream.h ObjFW/OFInflate64Stream.h * * @note This class only conforms to OFReadyForReadingObserving if the * underlying stream does so, too. * @@ -70,11 +70,11 @@ } huffman; } _context; bool _inLastBlock, _atEndOfStream; } -/*! +/** * @brief Creates a new OFInflate64Stream with the specified underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A new, autoreleased OFInflate64Stream @@ -81,11 +81,11 @@ */ + (instancetype)streamWithStream: (OFStream *)stream; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFInflate64Stream with the specified * underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read Index: src/OFInflateStream.h ================================================================== --- src/OFInflateStream.h +++ src/OFInflateStream.h @@ -20,11 +20,11 @@ OF_ASSUME_NONNULL_BEGIN #define OF_INFLATE_STREAM_BUFFER_SIZE 4096 -/*! +/** * @class OFInflateStream OFInflateStream.h ObjFW/OFInflateStream.h * * @note This class only conforms to OFReadyForReadingObserving if the * underlying stream does so, too. * @@ -70,11 +70,11 @@ } huffman; } _context; bool _inLastBlock, _atEndOfStream; } -/*! +/** * @brief Creates a new OFInflateStream with the specified underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A new, autoreleased OFInflateStream @@ -81,11 +81,11 @@ */ + (instancetype)streamWithStream: (OFStream *)stream; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFInflateStream with the specified * underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read Index: src/OFInflateStream.m ================================================================== --- src/OFInflateStream.m +++ src/OFInflateStream.m @@ -228,11 +228,11 @@ - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { unsigned char *buffer = buffer_; - uint16_t bits, tmp, value; + uint16_t bits = 0, tmp, value = 0; size_t bytesWritten = 0; unsigned char *slidingWindow; uint16_t slidingWindowIndex; if (_stream == nil) Index: src/OFInvocation.h ================================================================== --- src/OFInvocation.h +++ src/OFInvocation.h @@ -33,81 +33,81 @@ @class OFMethodSignature; @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableData; -/*! +/** * @class OFInvocation OFInvocation.h ObjFW/OFInvocation.h * * @brief A class for storing and accessing invocations, and invoking them. */ @interface OFInvocation: OFObject { OFMethodSignature *_methodSignature; OFMutableArray OF_GENERIC(OFMutableData *) *_arguments; OFMutableData *_returnValue; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFInvocation, 4) } -/*! +/** * @brief The method signature for the invocation. */ @property (readonly, nonatomic) OFMethodSignature *methodSignature; -/*! +/** * @brief Creates a new invocation with the specified method signature. * * @param signature The method signature for the invocation * @return A new, autoreleased OFInvocation */ + (instancetype)invocationWithMethodSignature: (OFMethodSignature *)signature; -/*! +/** * @brief Initializes an already allocated invocation with the specified method * signature. * * @param signature The method signature for the invocation * @return An initialized OFInvocation */ - (instancetype)initWithMethodSignature: (OFMethodSignature *)signature; -/*! +/** * @brief Sets the argument for the specified index. * * @param buffer The buffer in which the argument is stored * @param index The index of the argument to set */ - (void)setArgument: (const void *)buffer atIndex: (size_t)index; -/*! +/** * @brief Gets the argument for the specified index. * * @param buffer The buffer in which the argument is stored * @param index The index of the argument to get */ - (void)getArgument: (void *)buffer atIndex: (size_t)index; -/*! +/** * @brief Sets the return value. * * @param buffer The buffer in which the return value is stored */ - (void)setReturnValue: (const void *)buffer; -/*! +/** * @brief Gets the return value. * * @param buffer The buffer in which the return value is stored */ - (void)getReturnValue: (void *)buffer; #ifdef OF_INVOCATION_CAN_INVOKE -/*! +/** * @brief Invokes the method. */ - (void)invoke; #endif @end OF_ASSUME_NONNULL_END Index: src/OFJSONRepresentation.h ================================================================== --- src/OFJSONRepresentation.h +++ src/OFJSONRepresentation.h @@ -25,11 +25,11 @@ OF_JSON_REPRESENTATION_PRETTY = 0x01, OF_JSON_REPRESENTATION_JSON5 = 0x02, OF_JSON_REPRESENTATION_IDENTIFIER = 0x10 }; -/*! +/** * @protocol OFJSONRepresentation * OFJSONRepresentation.h ObjFW/OFJSONRepresentation.h * * @brief A protocol implemented by classes that support encoding to a JSON * representation. @@ -37,16 +37,16 @@ * @warning Although this method can be called directly on classes other than * OFArray and OFDictionary, this will generate invalid JSON, as JSON * requires all data to be encapsulated in an array or a dictionary! */ @protocol OFJSONRepresentation -/*! +/** * @brief The JSON representation of the object as a string. */ @property (readonly, nonatomic) OFString *JSONRepresentation; -/*! +/** * @brief Returns the JSON representation of the object as a string. * * @param options The options to use when creating a JSON representation.@n * Possible values are: * Value | Description Index: src/OFKernelEventObserver.h ================================================================== --- src/OFKernelEventObserver.h +++ src/OFKernelEventObserver.h @@ -33,20 +33,20 @@ #ifdef OF_HAVE_THREADS @class OFMutex; #endif @class OFMutableData; -/*! +/** * @protocol OFKernelEventObserverDelegate * OFKernelEventObserver.h ObjFW/OFKernelEventObserver.h * * @brief A protocol that needs to be implemented by delegates for * OFKernelEventObserver. */ @protocol OFKernelEventObserverDelegate @optional -/*! +/** * @brief This callback is called when an object did get ready for reading. * * @note If the object is a subclass of @ref OFStream and * @ref OFStream::tryReadLine or @ref OFStream::tryReadTillDelimiter: has * been called on the stream, this callback will not be called again @@ -58,59 +58,59 @@ * * @param object The object which did become ready for reading */ - (void)objectIsReadyForReading: (id)object; -/*! +/** * @brief This callback is called when an object did get ready for writing. * * @param object The object which did become ready for writing */ - (void)objectIsReadyForWriting: (id)object; #ifdef OF_AMIGAOS -/*! +/** * @brief This callback is called when an Exec Signal was received. * * @note This is only available on AmigaOS! */ - (void)execSignalWasReceived: (ULONG)signalMask; #endif @end -/*! +/** * @protocol OFReadyForReadingObserving * OFKernelEventObserver.h ObjFW/OFKernelEventObserver.h * * @brief This protocol is implemented by classes which can be observed for * readiness for reading by OFKernelEventObserver. */ @protocol OFReadyForReadingObserving -/*! +/** * @brief The file descriptor for reading that should be checked by the * OFKernelEventObserver. */ @property (readonly, nonatomic) int fileDescriptorForReading; @end -/*! +/** * @protocol OFReadyForWritingObserving * OFKernelEventObserver.h ObjFW/OFKernelEventObserver.h * * @brief This protocol is implemented by classes which can be observed for * readiness for writing by OFKernelEventObserver. */ @protocol OFReadyForWritingObserving -/*! +/** * @brief The file descriptor for writing that should be checked by the * OFKernelEventObserver. */ @property (readonly, nonatomic) int fileDescriptorForWriting; @end #ifdef OF_HAVE_SOCKETS -/*! +/** * @class OFKernelEventObserver * OFKernelEventObserver.h ObjFW/OFKernelEventObserver.h * * @brief A class that can observe multiple kernel events (e.g. streams being * ready to read) at once. @@ -134,36 +134,36 @@ struct sockaddr_in _cancelAddr; #endif #ifdef OF_AMIGAOS ULONG _execSignalMask; #endif - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFKernelEventObserver, 4) } -/*! +/** * @brief The delegate for the OFKernelEventObserver. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; #ifdef OF_AMIGAOS -/*! +/** * @brief A mask of Exec Signals to wait for. * * @note This is only available on AmigaOS! */ @property (nonatomic) ULONG execSignalMask; #endif -/*! +/** * @brief Creates a new OFKernelEventObserver. * * @return A new, autoreleased OFKernelEventObserver */ + (instancetype)observer; -/*! +/** * @brief Adds an object to observe for reading. * * This is also used to observe a listening socket for incoming connections, * which then triggers a read event for the observed object. * @@ -172,74 +172,74 @@ * * @param object The object to observe for reading */ - (void)addObjectForReading: (id )object; -/*! +/** * @brief Adds an object to observe for writing. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent blocking even though the newly added object is ready. * * @param object The object to observe for writing */ - (void)addObjectForWriting: (id )object; -/*! +/** * @brief Removes an object to observe for reading. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent the removed object from still being observed. * * @param object The object to remove from observing for reading */ - (void)removeObjectForReading: (id )object; -/*! +/** * @brief Removes an object to observe for writing. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent the removed object from still being observed. * * @param object The object to remove from observing for writing */ - (void)removeObjectForWriting: (id )object; -/*! +/** * @brief Observes all objects and blocks until an event happens on an object. */ - (void)observe; -/*! +/** * @brief Observes all objects until an event happens on an object or the * timeout is reached. * * @param timeInterval The time to wait for an event, in seconds */ - (void)observeForTimeInterval: (of_time_interval_t)timeInterval; -/*! +/** * @brief Observes all objects until an event happens on an object or the * specified date is reached. * * @param date The until which to observe */ - (void)observeUntilDate: (OFDate *)date; -/*! +/** * @brief Cancels the currently blocking observe call. * * This is the only method that can and should be called from another thread * than the one using the observer. */ - (void)cancel; -/*! +/** * @brief This method should be called by subclasses in @ref observeUntilDate: * as the first thing to handle all sockets that currently have data in * the read buffer. */ - (bool)of_processReadBuffers; @end #endif OF_ASSUME_NONNULL_END Index: src/OFKeyValueCoding.h ================================================================== --- src/OFKeyValueCoding.h +++ src/OFKeyValueCoding.h @@ -19,36 +19,36 @@ @class OFString; OF_ASSUME_NONNULL_BEGIN -/*! +/** * @protocol OFKeyValueCoding OFKeyValueCoding.h ObjFW/OFKeyValueCoding.h * * @brief A protocol for Key Value Coding. * * Key Value Coding makes it possible to access properties dynamically using * the interface described by this protocol. */ @protocol OFKeyValueCoding -/*! +/** * @brief Returns the value for the specified key. * * @param key The key of the value to return * @return The value for the specified key */ - (nullable id)valueForKey: (OFString *)key; -/*! +/** * @brief Returns the value for the specified key path. * * @param keyPath The key path of the value to return * @return The value for the specified key path */ - (nullable id)valueForKeyPath: (OFString *)keyPath; -/*! +/** * @brief This is called by @ref valueForKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * @@ -55,29 +55,29 @@ * @param key The undefined key of the value to return * @return The value for the specified undefined key */ - (nullable id)valueForUndefinedKey: (OFString *)key; -/*! +/** * @brief Set the value for the specified key. * * @param value The value for the specified key * @param key The key of the value to set */ - (void)setValue: (nullable id)value forKey: (OFString *)key; -/*! +/** * @brief Set the value for the specified key path. * * @param value The value for the specified key path * @param keyPath The key path of the value to set */ - (void)setValue: (nullable id)value forKeyPath: (OFString *)keyPath; -/*! +/** * @brief This is called by @ref setValue:forKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * @@ -85,11 +85,11 @@ * @param key The undefined key of the value to set */ - (void)setValue: (nullable id)value forUndefinedKey: (OFString *)key; -/*! +/** * @brief This is called by @ref setValue:forKey: if the specified key is a * scalar, but the value specified is `nil`. * * By default, this throws an @ref OFInvalidArgumentException. * Index: src/OFKqueueKernelEventObserver.m ================================================================== --- src/OFKqueueKernelEventObserver.m +++ src/OFKqueueKernelEventObserver.m @@ -163,11 +163,11 @@ if ([self of_processReadBuffers]) return; timeout.tv_sec = (time_t)timeInterval; - timeout.tv_nsec = (timeInterval - timeout.tv_sec) * 1000000000; + timeout.tv_nsec = (long)((timeInterval - timeout.tv_sec) * 1000000000); events = kevent(_kernelQueue, NULL, 0, eventList, EVENTLIST_SIZE, (timeInterval != -1 ? &timeout : NULL)); if (events < 0) Index: src/OFLHAArchive.h ================================================================== --- src/OFLHAArchive.h +++ src/OFLHAArchive.h @@ -22,11 +22,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFStream; -/*! +/** * @class OFLHAArchive OFLHAArchive.h ObjFW/OFLHAArchive.h * * @brief A class for accessing and manipulating LHA files. */ OF_SUBCLASSING_RESTRICTED @@ -40,27 +40,26 @@ } _mode; of_string_encoding_t _encoding; OFStream *_Nullable _lastReturnedStream; } -/*! +/** * @brief The encoding to use for the archive. Defaults to ISO 8859-1. */ @property (nonatomic) of_string_encoding_t encoding; -/*! +/** * @brief A stream for reading the current entry. * * @note This is only available in read mode. * - * @note The returned stream only conforms to @ref OFReadyForReadingObserving if - * the underlying stream does so, too. + * @note The returned stream conforms to @ref OFReadyForReadingObserving if the + * underlying stream does so, too. */ -@property (readonly, nonatomic) - OFStream *streamForReadingCurrentEntry; +@property (readonly, nonatomic) OFStream *streamForReadingCurrentEntry; -/*! +/** * @brief Creates a new OFLHAArchive object with the specified stream. * * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, @@ -70,11 +69,11 @@ */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a new OFLHAArchive object with the specified file. * * @param path The path to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing @@ -85,11 +84,11 @@ mode: (OFString *)mode; #endif - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFLHAArchive object with the * specified stream. * * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. @@ -100,11 +99,11 @@ */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES -/*! +/** * @brief Initializes an already allocated OFLHAArchive object with the * specified file. * * @param path The path to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, @@ -114,11 +113,11 @@ */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; #endif -/*! +/** * @brief Returns the next entry from the LHA archive or `nil` if all entries * have been read. * * @note This is only available in read mode. * @@ -131,20 +130,20 @@ * @return The next entry from the LHA archive or `nil` if all entries have * been read */ - (nullable OFLHAArchiveEntry *)nextEntry; -/*! +/** * @brief Returns a stream for writing the specified entry. * * @note This is only available in write and append mode. * * @note The uncompressed size, compressed size and CRC16 of the specified * entry are ignored. * - * @note The returned stream only conforms to @ref OFReadyForWritingObserving if - * the underlying stream does so, too. + * @note The returned stream conforms to @ref OFReadyForWritingObserving if the + * underlying stream does so, too. * * @warning Calling @ref nextEntry will invalidate all streams returned by * @ref streamForReadingCurrentEntry or * @ref streamForWritingEntry:! Reading from or writing to an * invalidated stream will throw an @ref OFReadFailedException or @@ -151,15 +150,14 @@ * @ref OFWriteFailedException! * * @param entry The entry for which a stream for writing should be returned * @return A stream for writing the specified entry */ -- (OFStream *) - streamForWritingEntry: (OFLHAArchiveEntry *)entry; +- (OFStream *)streamForWritingEntry: (OFLHAArchiveEntry *)entry; -/*! +/** * @brief Closes the OFLHAArchive. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFLHAArchive.m ================================================================== --- src/OFLHAArchive.m +++ src/OFLHAArchive.m @@ -203,11 +203,11 @@ entry: entry]; return entry; } -- (OFStream *)streamForReadingCurrentEntry +- (OFStream *)streamForReadingCurrentEntry { if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @@ -215,12 +215,11 @@ return [[(OFLHAArchiveFileReadStream *)_lastReturnedStream retain] autorelease]; } -- (OFStream *) - streamForWritingEntry: (OFLHAArchiveEntry *)entry +- (OFStream *)streamForWritingEntry: (OFLHAArchiveEntry *)entry { OFString *compressionMethod; if (_mode != OF_LHA_ARCHIVE_MODE_WRITE && _mode != OF_LHA_ARCHIVE_MODE_APPEND) Index: src/OFLHAArchiveEntry.h ================================================================== --- src/OFLHAArchiveEntry.h +++ src/OFLHAArchiveEntry.h @@ -24,11 +24,11 @@ @class OFDate; @class OFMutableArray OF_GENERIC(ObjectType); @class OFNumber; @class OFString; -/*! +/** * @class OFLHAArchiveEntry OFLHAArchiveEntry.h ObjFW/OFLHAArchiveEntry.h * * @brief A class which represents an entry in an LHA archive. */ @interface OFLHAArchiveEntry: OFObject @@ -42,106 +42,106 @@ OFString *_Nullable _fileComment; OFNumber *_Nullable _mode, *_Nullable _UID, *_Nullable _GID; OFString *_Nullable _owner, *_Nullable _group; OFDate *_Nullable _modificationDate; OFMutableArray OF_GENERIC(OFData *) *_extensions; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFLHAArchiveEntry, 4) } -/*! +/** * @brief The file name of the entry. */ @property (readonly, copy, nonatomic) OFString *fileName; -/*! +/** * @brief The compression method of the entry. */ @property (readonly, copy, nonatomic) OFString *compressionMethod; -/*! +/** * @brief The compressed size of the entry's file. */ @property (readonly, nonatomic) uint32_t compressedSize; -/*! +/** * @brief The uncompressed size of the entry's file. */ @property (readonly, nonatomic) uint32_t uncompressedSize; -/*! +/** * @brief The date of the file. */ @property (readonly, retain, nonatomic) OFDate *date; -/*! +/** * @brief The LHA level of the file. */ @property (readonly, nonatomic) uint8_t headerLevel; -/*! +/** * @brief The CRC16 of the file. */ @property (readonly, nonatomic) uint16_t CRC16; -/*! +/** * @brief The operating system identifier of the file. */ @property (readonly, nonatomic) uint8_t operatingSystemIdentifier; -/*! +/** * @brief The comment of the file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *fileComment; -/*! +/** * @brief The mode of the entry. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFNumber *mode; -/*! +/** * @brief The UID of the owner. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFNumber *UID; -/*! +/** * @brief The GID of the group. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFNumber *GID; -/*! +/** * @brief The owner of the file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *owner; -/*! +/** * @brief The group of the file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *group; -/*! +/** * @brief The date of the last modification of the file. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFDate *modificationDate; -/*! +/** * @brief The LHA extensions of the file. */ @property (readonly, copy, nonatomic) OFArray OF_GENERIC(OFData *) *extensions; -/*! +/** * @brief Creates a new OFLHAArchiveEntry with the specified file name. * * @param fileName The file name for the OFLHAArchiveEntry * @return A new, autoreleased OFLHAArchiveEntry */ + (instancetype)entryWithFileName: (OFString *)fileName; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFLHAArchiveEntry with the specified * file name. * * @param fileName The file name for the OFLHAArchiveEntry * @return An initialized OFLHAArchiveEntry Index: src/OFLHAArchiveEntry.m ================================================================== --- src/OFLHAArchiveEntry.m +++ src/OFLHAArchiveEntry.m @@ -125,11 +125,11 @@ mode = OF_BSWAP16_IF_BE(mode); [entry->_mode release]; entry->_mode = nil; - entry->_mode = [[OFNumber alloc] initWithUInt16: mode]; + entry->_mode = [[OFNumber alloc] initWithUnsignedShort: mode]; } static void parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) @@ -149,12 +149,12 @@ entry->_GID = nil; [entry->_UID release]; entry->_UID = nil; - entry->_GID = [[OFNumber alloc] initWithUInt16: GID]; - entry->_UID = [[OFNumber alloc] initWithUInt16: UID]; + entry->_GID = [[OFNumber alloc] initWithUnsignedShort: GID]; + entry->_UID = [[OFNumber alloc] initWithUnsignedShort: UID]; } static void parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) @@ -653,11 +653,11 @@ tmp16 = OF_BSWAP16_IF_BE(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; - tmp16 = OF_BSWAP16_IF_BE(_mode.uInt16Value); + tmp16 = OF_BSWAP16_IF_BE(_mode.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_UID != nil || _GID != nil) { @@ -667,15 +667,15 @@ tmp16 = OF_BSWAP16_IF_BE(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x51"]; - tmp16 = OF_BSWAP16_IF_BE(_GID.uInt16Value); + tmp16 = OF_BSWAP16_IF_BE(_GID.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; - tmp16 = OF_BSWAP16_IF_BE(_UID.uInt16Value); + tmp16 = OF_BSWAP16_IF_BE(_UID.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_group != nil) { @@ -759,11 +759,11 @@ - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFString *mode = (_mode == nil ? nil - : [OFString stringWithFormat: @"%" PRIo16, _mode.uInt16Value]); + : [OFString stringWithFormat: @"%ho", _mode.unsignedShortValue]); OFString *extensions = [_extensions.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; OFString *ret = [OFString stringWithFormat: @"<%@:\n" Index: src/OFLHADecompressingStream.m ================================================================== --- src/OFLHADecompressingStream.m +++ src/OFLHADecompressingStream.m @@ -138,11 +138,11 @@ - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { unsigned char *buffer = buffer_; - uint16_t bits, value; + uint16_t bits = 0, value = 0; size_t bytesWritten = 0; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; Index: src/OFList.h ================================================================== --- src/OFList.h +++ src/OFList.h @@ -21,28 +21,28 @@ #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN typedef struct of_list_object_t of_list_object_t; -/*! +/** * @struct of_list_object_t OFList.h ObjFW/OFList.h * * @brief A list object. * * A struct that contains a pointer to the next list object, the previous list * object and the object. */ struct of_list_object_t { - /*! A pointer to the next list object in the list */ + /** A pointer to the next list object in the list */ of_list_object_t *_Nullable next; - /*! A pointer to the previous list object in the list */ + /** A pointer to the previous list object in the list */ of_list_object_t *_Nullable previous; - /*! The object for the list object */ + /** The object for the list object */ id __unsafe_unretained object; }; -/*! +/** * @class OFList OFList.h ObjFW/OFList.h * * @brief A class which provides easy to use double-linked lists. */ @interface OFList OF_GENERIC(ObjectType): OFObject -/*! +/** * @brief The name of the lock. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *name; -/*! +/** * @brief Locks the lock. */ - (void)lock; -/*! +/** * @brief Tries to lock the lock. * * @return A boolean whether the lock could be locked */ - (bool)tryLock; -/*! +/** * @brief Unlocks the lock. */ - (void)unlock; @end OF_ASSUME_NONNULL_END Index: src/OFMD5Hash.h ================================================================== --- src/OFMD5Hash.h +++ src/OFMD5Hash.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFSecureData; -/*! +/** * @class OFMD5Hash OFMD5Hash.h ObjFW/OFMD5Hash.h * * @brief A class which provides methods to create an MD5 hash. */ OF_SUBCLASSING_RESTRICTED Index: src/OFMapTable.h ================================================================== --- src/OFMapTable.h +++ src/OFMapTable.h @@ -18,32 +18,32 @@ #import "OFObject.h" #import "OFEnumerator.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ -/*! +/** * @struct of_map_table_functions_t OFMapTable.h ObjFW/OFMapTable.h * * @brief A struct describing the functions to be used by the map table. */ struct of_map_table_functions_t { - /*! The function to retain keys / objects */ + /** The function to retain keys / objects */ void *_Nullable (*_Nullable retain)(void *_Nullable object); - /*! The function to release keys / objects */ + /** The function to release keys / objects */ void (*_Nullable release)(void *_Nullable object); - /*! The function to hash keys */ + /** The function to hash keys */ uint32_t (*_Nullable hash)(void *_Nullable object); - /*! The function to compare keys / objects */ + /** 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; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for enumerating an OFMapTable. * * @param key The current key * @param object The current object * @param stop A pointer to a variable that can be set to true to stop the @@ -50,11 +50,11 @@ * enumeration */ typedef void (^of_map_table_enumeration_block_t)(void *_Nullable key, void *_Nullable object, bool *stop); -/*! +/** * @brief A block for replacing objects in an OFMapTable. * * @param key The key of the object to replace * @param object The object to replace * @return The object to replace the object with @@ -63,11 +63,11 @@ void *_Nullable object); #endif @class OFMapTableEnumerator; -/*! +/** * @class OFMapTable OFMapTable.h ObjFW/OFMapTable.h * * @brief A class similar to OFDictionary, but providing more options how keys * and objects should be retained, released, compared and hashed. */ @@ -79,26 +79,26 @@ uint32_t _count, _capacity; uint8_t _rotate; unsigned long _mutations; } -/*! +/** * @brief The key functions used by the map table. */ @property (readonly, nonatomic) of_map_table_functions_t keyFunctions; -/*! +/** * @brief The object functions used by the map table. */ @property (readonly, nonatomic) of_map_table_functions_t objectFunctions; -/*! +/** * @brief The number of objects in the map table. */ @property (readonly, nonatomic) size_t count; -/*! +/** * @brief Creates a new OFMapTable with the specified key and object functions. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects * @return A new autoreleased OFMapTable @@ -105,11 +105,11 @@ */ + (instancetype)mapTableWithKeyFunctions: (of_map_table_functions_t)keyFunctions objectFunctions: (of_map_table_functions_t) objectFunctions; -/*! +/** * @brief Creates a new OFMapTable with the specified key functions, object * functions and capacity. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects @@ -122,11 +122,11 @@ objectFunctions capacity: (size_t)capacity; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFMapTable with the specified key * and object functions. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects @@ -133,11 +133,11 @@ * @return An initialized OFMapTable */ - (instancetype)initWithKeyFunctions: (of_map_table_functions_t)keyFunctions objectFunctions: (of_map_table_functions_t)objectFunctions; -/*! +/** * @brief Initializes an already allocated OFMapTable with the specified key * functions, object functions and capacity. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects @@ -148,93 +148,93 @@ - (instancetype)initWithKeyFunctions: (of_map_table_functions_t)keyFunctions objectFunctions: (of_map_table_functions_t)objectFunctions capacity: (size_t)capacity OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Returns the object for the given key or NULL if the key was not found. * * @param key The key whose object should be returned * @return The object for the given key or NULL if the key was not found */ - (nullable void *)objectForKey: (void *)key; -/*! +/** * @brief Sets an object for a key. * * @param key The key to set * @param object The object to set the key to */ - (void)setObject: (nullable void *)object forKey: (nullable void *)key; -/*! +/** * @brief Removes the object for the specified key from the map table. * * @param key The key whose object should be removed */ - (void)removeObjectForKey: (nullable void *)key; -/*! +/** * @brief Removes all objects. */ - (void)removeAllObjects; -/*! +/** * @brief Checks whether the map table contains an object equal to the * specified object. * * @param object The object which is checked for being in the map table * @return A boolean whether the map table contains the specified object */ - (bool)containsObject: (nullable void *)object; -/*! +/** * @brief Checks whether the map table contains an object with the specified * address. * * @param object The object which is checked for being in the map table * @return A boolean whether the map table contains an object with the * specified address. */ - (bool)containsObjectIdenticalTo: (nullable void *)object; -/*! +/** * @brief Returns an OFMapTableEnumerator to enumerate through the map table's * keys. * * @return An OFMapTableEnumerator to enumerate through the map table's keys */ - (OFMapTableEnumerator *)keyEnumerator; -/*! +/** * @brief Returns an OFMapTableEnumerator to enumerate through the map table's * objects. * * @return An OFMapTableEnumerator to enumerate through the map table's objects */ - (OFMapTableEnumerator *)objectEnumerator; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Executes a block for each key / object pair. * * @param block The block to execute for each key / object pair. */ - (void)enumerateKeysAndObjectsUsingBlock: (of_map_table_enumeration_block_t)block; -/*! +/** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ - (void)replaceObjectsUsingBlock: (of_map_table_replace_block_t)block; #endif @end -/*! +/** * @class OFMapTableEnumerator OFMapTable.h ObjFW/OFMapTable.h * * @brief A class which provides methods to enumerate through an OFMapTable's * keys or objects. */ @@ -248,15 +248,15 @@ uint32_t _position; } - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Returns a pointer to the next object, or NULL if the enumeration * finished. * * @return The next object */ - (void *_Nullable *_Nullable)nextObject; @end OF_ASSUME_NONNULL_END Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -165,11 +165,11 @@ _buckets = [self allocZeroedMemoryWithSize: sizeof(*_buckets) count: _capacity]; if (of_hash_seed != 0) - _rotate = of_random() & 31; + _rotate = of_random16() & 31; } @catch (id e) { [self release]; @throw e; } @@ -532,11 +532,11 @@ /* * Get a new random value for _rotate, so that it is not less secure * than creating a new hash map. */ if (of_hash_seed != 0) - _rotate = of_random() & 31; + _rotate = of_random16() & 31; } - (bool)containsObject: (void *)object { if (object == NULL || _count == 0) Index: src/OFMessagePackExtension.h ================================================================== --- src/OFMessagePackExtension.h +++ src/OFMessagePackExtension.h @@ -20,11 +20,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; -/*! +/** * @class OFMessagePackExtension \ * OFMessagePackExtension.h ObjFW/OFMessagePackExtension.h * * @brief A class for representing the MessagePack extension type. */ @@ -31,24 +31,24 @@ @interface OFMessagePackExtension: OFObject { int8_t _type; OFData *_data; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMessagePackExtension, 4) } -/*! +/** * @brief The MessagePack extension type. */ @property (readonly, nonatomic) int8_t type; -/*! +/** * @brief The data of the extension. */ @property (readonly, nonatomic) OFData *data; -/*! +/** * @brief Creates a new OFMessagePackRepresentation with the specified type and * data. * * @param type The MessagePack extension type * @param data The data for the extension @@ -57,11 +57,11 @@ + (instancetype)extensionWithType: (int8_t)type data: (OFData *)data; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFMessagePackRepresentation with the * specified type and data. * * @param type The MessagePack extension type * @param data The data for the extension Index: src/OFMessagePackRepresentation.h ================================================================== --- src/OFMessagePackRepresentation.h +++ src/OFMessagePackRepresentation.h @@ -19,20 +19,20 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; -/*! +/** * @protocol OFMessagePackRepresentation \ * OFMessagePackRepresentation.h ObjFW/OFMessagePackRepresentation.h * * @brief A protocol implemented by classes that support encoding to a * MessagePack representation. */ @protocol OFMessagePackRepresentation -/*! +/** * @brief The MessagePack representation of the object as OFData. */ @property (readonly, nonatomic) OFData *messagePackRepresentation; @end OF_ASSUME_NONNULL_END Index: src/OFMethodSignature.h ================================================================== --- src/OFMethodSignature.h +++ src/OFMethodSignature.h @@ -19,65 +19,65 @@ OF_ASSUME_NONNULL_BEGIN @class OFMutableData; -/*! +/** * @class OFMethodSignature OFMethodSignature.h ObjFW/OFMethodSignature.h * * @brief A class for parsing type encodings and accessing them. */ @interface OFMethodSignature: OFObject { char *_types; OFMutableData *_typesPointers, *_offsets; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMethodSignature, 4) } -/*! +/** * @brief The number of arguments of the method. */ @property (readonly, nonatomic) size_t numberOfArguments; -/*! +/** * @brief The return type of the method. */ @property (readonly, nonatomic) const char *methodReturnType; -/*! +/** * @brief The size of the arguments on the stack frame. * * @note This is platform-dependent! */ @property (readonly, nonatomic) size_t frameLength; -/*! +/** * @brief Creates a new OFMethodSignature with the specified ObjC types. * * @param types The ObjC types of the method * @return A new, autoreleased OFMethodSignature */ + (instancetype)signatureWithObjCTypes: (const char *)types; -/*! +/** * @brief Initializes an already allocated OFMethodSignature with the specified * ObjC types. * * @param types The ObjC types of the method * @return An Initialized OFMethodSignature */ - (instancetype)initWithObjCTypes: (const char *)types; -/*! +/** * @brief Returns the ObjC type for the argument at the specified index. * * @param index The index of the argument for which to return the ObjC type * @return The ObjC type for the argument at the specified index */ - (const char *)argumentTypeAtIndex: (size_t)index; -/*! +/** * @brief Returns the offset on the stack frame of the argument at the * specified index. * * @note This is platform-dependent! * @@ -88,19 +88,19 @@ @end #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief Returns the size for the specified type encoding. * * @param type The type encoding to return the size for * @return The size for the specified type encoding */ extern size_t of_sizeof_type_encoding(const char *type); -/*! +/** * @brief Returns the alignment for the specified type encoding. * * @param type The type encoding to return the alignment for * @return The alignment for the specified type encoding */ Index: src/OFMutableArray.h ================================================================== --- src/OFMutableArray.h +++ src/OFMutableArray.h @@ -17,24 +17,24 @@ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for replacing values in an OFMutableArray. * * @param object The object to replace * @param index The index of the object to replace * @return The object to replace the object with */ typedef id _Nonnull (^of_array_replace_block_t)(id object, size_t index); #endif -/*! +/** * @class OFMutableArray OFArray.h ObjFW/OFArray.h * * @brief An abstract class for storing, adding and removing objects in an * array. * @@ -44,80 +44,80 @@ */ @interface OFMutableArray OF_GENERIC(ObjectType): OFArray OF_GENERIC(ObjectType) #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif -/*! +/** * @brief Creates a new OFMutableArray with enough memory to hold the specified * number of objects. * * @param capacity The initial capacity for the OFMutableArray * @return A new autoreleased OFMutableArray */ + (instancetype)arrayWithCapacity: (size_t)capacity; -/*! +/** * @brief Initializes an already allocated OFMutableArray with enough memory to * hold the specified number of objects. * * @param capacity The initial capacity for the OFMutableArray * @return An initialized OFMutableArray */ - (instancetype)initWithCapacity: (size_t)capacity; -/*! +/** * @brief Adds an object to the end of the array. * * @param object An object to add */ - (void)addObject: (ObjectType)object; -/*! +/** * @brief Adds the objects from the specified OFArray to the end of the array. * * @param array An array of objects to add */ - (void)addObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array; -/*! +/** * @brief Inserts an object to the OFArray at the specified index. * * @param object An object to add * @param index The index where the object should be inserted */ - (void)insertObject: (ObjectType)object atIndex: (size_t)index; -/*! +/** * @brief Inserts the objects from the specified OFArray at the specified index. * * @param array An array of objects * @param index The index where the objects should be inserted */ - (void)insertObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array atIndex: (size_t)index; -/*! +/** * @brief Replaces the first object equivalent to the specified object with the * other specified object. * * @param oldObject The object to replace * @param newObject The replacement object */ - (void)replaceObject: (ObjectType)oldObject withObject: (ObjectType)newObject; -/*! +/** * @brief Replaces the object at the specified index with the specified object. * * @param index The index of the object to replace * @param object The replacement object */ - (void)replaceObjectAtIndex: (size_t)index withObject: (ObjectType)object; -/*! +/** * @brief Replaces the object at the specified index with the specified object. * * This method is the same as @ref replaceObjectAtIndex:withObject:. * * This method is also used by the subscripting syntax. @@ -126,83 +126,83 @@ * @param object The replacement object */ - (void)setObject: (ObjectType)object atIndexedSubscript: (size_t)index; -/*! +/** * @brief Replaces the first object that has the same address as the specified * object with the other specified object. * * @param oldObject The object to replace * @param newObject The replacement object */ - (void)replaceObjectIdenticalTo: (ObjectType)oldObject withObject: (ObjectType)newObject; -/*! +/** * @brief Removes the first object equivalent to the specified object. * * @param object The object to remove */ - (void)removeObject: (ObjectType)object; -/*! +/** * @brief Removes the first object that has the same address as the specified * object. * * @param object The object to remove */ - (void)removeObjectIdenticalTo: (ObjectType)object; -/*! +/** * @brief Removes the object at the specified index. * * @param index The index of the object to remove */ - (void)removeObjectAtIndex: (size_t)index; -/*! +/** * @brief Removes the object in the specified range. * * @param range The range of the objects to remove */ - (void)removeObjectsInRange: (of_range_t)range; -/*! +/** * @brief Removes the last object. */ - (void)removeLastObject; -/*! +/** * @brief Removes all objects. */ - (void)removeAllObjects; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ - (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block; #endif -/*! +/** * @brief Exchange the objects at the specified indices. * * @param index1 The index of the first object to exchange * @param index2 The index of the second object to exchange */ - (void)exchangeObjectAtIndex: (size_t)index1 withObjectAtIndex: (size_t)index2; -/*! +/** * @brief Sorts the array in ascending order. */ - (void)sort; -/*! +/** * @brief Sorts the array using the specified selector and options. * * @param selector The selector to use to sort the array. It's signature * should be the same as that of -[compare:]. * @param options The options to use when sorting the array.@n @@ -213,11 +213,11 @@ */ - (void)sortUsingSelector: (SEL)selector options: (int)options; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Sorts the array using the specified comparator and options. * * @param comparator The comparator to use to sort the array * @param options The options to use when sorting the array.@n * Possible values are: @@ -227,20 +227,20 @@ */ - (void)sortUsingComparator: (of_comparator_t)comparator options: (int)options; #endif -/*! +/** * @brief Reverts the order of the objects in the array. */ - (void)reverse; -/*! +/** * @brief Converts the mutable array to an immutable array. */ - (void)makeImmutable; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END Index: src/OFMutableData.h ================================================================== --- src/OFMutableData.h +++ src/OFMutableData.h @@ -20,69 +20,69 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFURL; -/*! +/** * @class OFMutableData OFMutableData.h ObjFW/OFMutableData.h * * @brief A class for storing and manipulating arbitrary data in an array. */ @interface OFMutableData: OFData { size_t _capacity; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutableData, 4) } -/*! +/** * @brief All items of the OFMutableData as a C array. * * @warning The pointer is only valid until the OFMutableData is changed! * * Modifying the returned array directly is allowed and will change the contents * of the data. */ @property (readonly, nonatomic) void *mutableItems OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The first item of the OFMutableData or `NULL`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *mutableFirstItem OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The last item of the OFMutableData or `NULL`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *mutableLastItem OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Creates a new OFMutableData with an item size of 1. * * @return A new autoreleased OFMutableData */ + (instancetype)data; -/*! +/** * @brief Creates a new OFMutableData whose items all have the same specified * size. * * @param itemSize The size of a single element in the OFMutableData * @return A new autoreleased OFMutableData */ + (instancetype)dataWithItemSize: (size_t)itemSize; -/*! +/** * @brief Creates a new OFMutableData with enough memory to hold the specified * number of items which all have an item size of 1. * * @param capacity The initial capacity for the OFMutableData * @return A new autoreleased OFMutableData */ + (instancetype)dataWithCapacity: (size_t)capacity; -/*! +/** * @brief Creates a new OFMutableData with enough memory to hold the specified * number of items which all have the same specified size. * * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData @@ -89,37 +89,37 @@ * @return A new autoreleased OFMutableData */ + (instancetype)dataWithItemSize: (size_t)itemSize capacity: (size_t)capacity; -/*! +/** * @brief Initializes an already allocated OFMutableData with an item size of 1. * * @return An initialized OFMutableData */ - (instancetype)init; -/*! +/** * @brief Initializes an already allocated OFMutableData whose items all have * the same size. * * @param itemSize The size of a single element in the OFMutableData * @return An initialized OFMutableData */ - (instancetype)initWithItemSize: (size_t)itemSize; -/*! +/** * @brief Initializes an already allocated OFMutableData with enough memory to * hold the the specified number of items which all have an item size of * 1. * * @param capacity The initial capacity for the OFMutableData * @return An initialized OFMutableData */ - (instancetype)initWithCapacity: (size_t)capacity; -/*! +/** * @brief Initializes an already allocated OFMutableData with enough memory to * hold the the specified number of items which all have the same * specified size. * * @param itemSize The size of a single element in the OFMutableData @@ -127,11 +127,11 @@ * @return An initialized OFMutableData */ - (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity; -/*! +/** * @brief Returns a specific item of the OFMutableData. * * Modifying the returned item directly is allowed and will change the contents * of the data. * @@ -138,36 +138,36 @@ * @param index The number of the item to return * @return The specified item of the OFMutableData */ - (void *)mutableItemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Adds an item to the OFMutableData. * * @param item A pointer to an arbitrary item */ - (void)addItem: (const void *)item; -/*! +/** * @brief Adds an item to the OFMutableData at the specified index. * * @param item A pointer to an arbitrary item * @param index The index where the item should be added */ - (void)insertItem: (const void *)item atIndex: (size_t)index; -/*! +/** * @brief Adds items from a C array to the OFMutableData. * * @param items A C array containing the items to add * @param count The number of items to add */ - (void)addItems: (const void *)items count: (size_t)count; -/*! +/** * @brief Adds items from a C array to the OFMutableData at the specified index. * * @param items A C array containing the items to add * @param index The index where the items should be added * @param count The number of items to add @@ -174,44 +174,44 @@ */ - (void)insertItems: (const void *)items atIndex: (size_t)index count: (size_t)count; -/*! +/** * @brief Increases the count by the specified number. The new items are all * filled with null bytes. * * @param count The count by which to increase the count */ - (void)increaseCountBy: (size_t)count; -/*! +/** * @brief Removes the item at the specified index. * * @param index The index of the item to remove */ - (void)removeItemAtIndex: (size_t)index; -/*! +/** * @brief Removes the specified amount of items at the specified index. * * @param range The range of items to remove */ - (void)removeItemsInRange: (of_range_t)range; -/*! +/** * @brief Removes the last item. */ - (void)removeLastItem; -/*! +/** * @brief Removes all items. */ - (void)removeAllItems; -/*! +/** * @brief Converts the mutable URL to an immutable URL. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END Index: src/OFMutableDictionary.h ================================================================== --- src/OFMutableDictionary.h +++ src/OFMutableDictionary.h @@ -17,24 +17,24 @@ #import "OFDictionary.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for replacing objects in an OFMutableDictionary. * * @param key The key of the object to replace * @param object The object to replace * @return The object to replace the object with */ typedef id _Nonnull (^of_dictionary_replace_block_t)(id key, id object); #endif -/*! +/** * @class OFMutableDictionary OFDictionary.h ObjFW/OFDictionary.h * * @brief An abstract class for storing and changing objects in a dictionary. * * @note Subclasses must implement @ref setObject:forKey:, @@ -45,29 +45,29 @@ OFDictionary OF_GENERIC(KeyType, ObjectType) #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define KeyType id # define ObjectType id #endif -/*! +/** * @brief Creates a new OFMutableDictionary with enough memory to hold the * specified number of objects. * * @param capacity The initial capacity for the OFMutableDictionary * @return A new autoreleased OFMutableDictionary */ + (instancetype)dictionaryWithCapacity: (size_t)capacity; -/*! +/** * @brief Initializes an already allocated OFMutableDictionary with enough * memory to hold the specified number of objects. * * @param capacity The initial capacity for the OFMutableDictionary * @return An initialized OFMutableDictionary */ - (instancetype)initWithCapacity: (size_t)capacity; -/*! +/** * @brief Sets an object for a key. * * A key can be any object that conforms to the OFCopying protocol. * * @param key The key to set @@ -74,11 +74,11 @@ * @param object The object to set the key to */ - (void)setObject: (ObjectType)object forKey: (KeyType)key; -/*! +/** * @brief Sets an object for a key. * * A key can be any object that conforms to the OFCopying protocol. * * This method is also used by the subscripting syntax. @@ -88,40 +88,40 @@ * calling @ref removeObjectForKey:. */ - (void)setObject: (nullable ObjectType)object forKeyedSubscript: (KeyType)key; -/*! +/** * @brief Removes the object for the specified key from the dictionary. * * @param key The key whose object should be removed */ - (void)removeObjectForKey: (KeyType)key; -/*! +/** * @brief Removes all objects. */ - (void)removeAllObjects; -/*! +/** * @brief Adds the entries from the specified dictionary. * * @param dictionary The dictionary whose entries should be added */ - (void)addEntriesFromDictionary: (OFDictionary OF_GENERIC(KeyType, ObjectType) *)dictionary; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ - (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block; #endif -/*! +/** * @brief Converts the mutable dictionary to an immutable dictionary. */ - (void)makeImmutable; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef KeyType Index: src/OFMutableLHAArchiveEntry.h ================================================================== --- src/OFMutableLHAArchiveEntry.h +++ src/OFMutableLHAArchiveEntry.h @@ -17,106 +17,106 @@ #import "OFLHAArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutableLHAArchiveEntry \ * OFMutableLHAArchiveEntry.h ObjFW/OFMutableLHAArchiveEntry.h * * @brief A class which represents a mutable entry in an LHA archive. */ @interface OFMutableLHAArchiveEntry: OFLHAArchiveEntry { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutableLHAArchiveEntry, 4) } -/*! +/** * @brief The file name of the entry. */ @property (readwrite, copy, nonatomic) OFString *fileName; -/*! +/** * @brief The compression method of the entry. */ @property (readwrite, copy, nonatomic) OFString *compressionMethod; -/*! +/** * @brief The compressed size of the entry's file. */ @property (readwrite, nonatomic) uint32_t compressedSize; -/*! +/** * @brief The uncompressed size of the entry's file. */ @property (readwrite, nonatomic) uint32_t uncompressedSize; -/*! +/** * @brief The date of the file. */ @property (readwrite, retain, nonatomic) OFDate *date; -/*! +/** * @brief The LHA level of the file. */ @property (readwrite, nonatomic) uint8_t headerLevel; -/*! +/** * @brief The CRC16 of the file. */ @property (readwrite, nonatomic) uint16_t CRC16; -/*! +/** * @brief The operating system identifier of the file. */ @property (readwrite, nonatomic) uint8_t operatingSystemIdentifier; -/*! +/** * @brief The comment of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *fileComment; -/*! +/** * @brief The mode of the entry. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFNumber *mode; -/*! +/** * @brief The UID of the owner. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFNumber *UID; -/*! +/** * @brief The GID of the group. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFNumber *GID; -/*! +/** * @brief The owner of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *owner; -/*! +/** * @brief The group of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *group; -/*! +/** * @brief The date of the last modification of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFDate *modificationDate; -/*! +/** * @brief The LHA extensions of the file. */ @property (readwrite, copy, nonatomic) OFArray OF_GENERIC(OFData *) *extensions; -/*! +/** * @brief Converts the OFMutableLHAArchiveEntry to an immutable * OFLHAArchiveEntry. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END Index: src/OFMutablePair.h ================================================================== --- src/OFMutablePair.h +++ src/OFMutablePair.h @@ -17,11 +17,11 @@ #import "OFPair.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutablePair OFMutablePair.h ObjFW/OFMutablePair.h * * @brief A class for storing a pair of two objects. */ @interface OFMutablePair OF_GENERIC(FirstType, SecondType): @@ -29,24 +29,24 @@ #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define FirstType id # define SecondType id #endif { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutablePair, 4) } -/*! +/** * @brief The first object of the pair. */ @property (readwrite, nonatomic, retain) FirstType firstObject; -/*! +/** * @brief The second object of the pair. */ @property (readwrite, nonatomic, retain) SecondType secondObject; -/*! +/** * @brief Converts the mutable pair to an immutable pair. */ - (void)makeImmutable; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef FirstType Index: src/OFMutableSet.h ================================================================== --- src/OFMutableSet.h +++ src/OFMutableSet.h @@ -17,11 +17,11 @@ #import "OFSet.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutableSet OFSet.h ObjFW/OFSet.h * * @brief An abstract class for a mutable unordered set of unique objects. * * @note Subclasses must implement @ref addObject:, @ref removeObject: as well @@ -29,74 +29,74 @@ */ @interface OFMutableSet OF_GENERIC(ObjectType): OFSet OF_GENERIC(ObjectType) #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif -/*! +/** * @brief Creates a new OFMutableSet with enough memory to hold the specified * number of objects. * * @param capacity The initial capacity for the OFMutableSet * @return A new autoreleased OFMutableSet */ + (instancetype)setWithCapacity: (size_t)capacity; -/*! +/** * @brief Initializes an already allocated OFMutableSet with enough memory to * hold the specified number of objects. * * @param capacity The initial capacity for the OFMutableSet * @return An initialized OFMutableSet */ - (instancetype)initWithCapacity: (size_t)capacity; -/*! +/** * @brief Adds the specified object to the set. * * @param object The object to add to the set */ - (void)addObject: (ObjectType)object; -/*! +/** * @brief Removes the specified object from the set. * * @param object The object to remove from the set */ - (void)removeObject: (ObjectType)object; -/*! +/** * @brief Removes all objects from the receiver which are in the specified set. * * @param set The set whose objects will be removed from the receiver */ - (void)minusSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Removes all objects from the receiver which are not in the specified * set. * * @param set The set to intersect with */ - (void)intersectSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Creates a union of the receiver and the specified set. * * @param set The set to create the union with */ - (void)unionSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Removes all objects from the set. */ - (void)removeAllObjects; -/*! +/** * @brief Converts the mutable set to an immutable set. */ - (void)makeImmutable; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END Index: src/OFMutableString.h ================================================================== --- src/OFMutableString.h +++ src/OFMutableString.h @@ -21,68 +21,68 @@ #include "OFString.h" OF_ASSUME_NONNULL_BEGIN #ifdef __OBJC__ -/*! +/** * @class OFMutableString OFString.h ObjFW/OFString.h * * @brief A class for storing and modifying strings. */ @interface OFMutableString: OFString -/*! +/** * @brief Sets the character at the specified index. * * @param character The character to set * @param index The index where to set the character */ - (void)setCharacter: (of_unichar_t)character atIndex: (size_t)index; -/*! +/** * @brief Appends another OFString to the OFMutableString. * * @param string An OFString to append */ - (void)appendString: (OFString *)string; -/*! +/** * @brief Appends the specified characters to the OFMutableString. * * @param characters An array of characters to append * @param length The length of the array of characters */ - (void)appendCharacters: (const of_unichar_t *)characters length: (size_t)length; -/*! +/** * @brief Appends a UTF-8 encoded C string to the OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append */ - (void)appendUTF8String: (const char *)UTF8String; -/*! +/** * @brief Appends a UTF-8 encoded C string with the specified length to the * OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append * @param UTF8StringLength The length of the UTF-8 encoded C string */ - (void)appendUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; -/*! +/** * @brief Appends a C string with the specified encoding to the OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string */ - (void)appendCString: (const char *)cString encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Appends a C string with the specified encoding and length to the * OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string @@ -90,11 +90,11 @@ */ - (void)appendCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength; -/*! +/** * @brief Appends a formatted string to the OFMutableString. * * See `printf` for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -101,11 +101,11 @@ * * @param format A format string which generates the string to append */ - (void)appendFormat: (OFConstantString *)format, ...; -/*! +/** * @brief Appends a formatted string to the OFMutableString. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -114,76 +114,76 @@ * @param arguments The arguments used in the format string */ - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments; -/*! +/** * @brief Prepends another OFString to the OFMutableString. * * @param string An OFString to prepend */ - (void)prependString: (OFString *)string; -/*! +/** * @brief Reverses the string. */ - (void)reverse; -/*! +/** * @brief Converts the string to uppercase. */ - (void)uppercase; -/*! +/** * @brief Converts the string to lowercase. */ - (void)lowercase; -/*! +/** * @brief Capitalizes the string. * * @note This only considers spaces, tabs and newlines to be word delimiters! * Also note that this might change in the future to all word delimiters * specified by Unicode! */ - (void)capitalize; -/*! +/** * @brief Inserts a string at the specified index. * * @param string The string to insert * @param index The index */ - (void)insertString: (OFString *)string atIndex: (size_t)index; -/*! +/** * @brief Deletes the characters at the specified range. * * @param range The range of the characters which should be removed */ - (void)deleteCharactersInRange: (of_range_t)range; -/*! +/** * @brief Replaces the characters at the specified range. * * @param range The range of the characters which should be replaced * @param replacement The string to the replace the characters with */ - (void)replaceCharactersInRange: (of_range_t)range withString: (OFString *)replacement; -/*! +/** * @brief Replaces all occurrences of a string with another string. * * @param string The string to replace * @param replacement The string with which it should be replaced */ - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement; -/*! +/** * @brief Replaces all occurrences of a string in the specified range with * another string. * * @param string The string to replace * @param replacement The string with which it should be replaced @@ -194,30 +194,30 @@ - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (of_range_t)range; -/*! +/** * @brief Deletes all whitespaces at the beginning of the string. */ - (void)deleteLeadingWhitespaces; -/*! +/** * @brief Deletes all whitespaces at the end of the string. */ - (void)deleteTrailingWhitespaces; -/*! +/** * @brief Deletes all whitespaces at the beginning and the end of the string. */ - (void)deleteEnclosingWhitespaces; -/*! +/** * @brief Converts the mutable string to an immutable string. */ - (void)makeImmutable; @end #endif OF_ASSUME_NONNULL_END #endif Index: src/OFMutableTarArchiveEntry.h ================================================================== --- src/OFMutableTarArchiveEntry.h +++ src/OFMutableTarArchiveEntry.h @@ -17,87 +17,87 @@ #import "OFTarArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutableTarArchiveEntry \ * OFMutableTarArchiveEntry.h ObjFW/OFMutableTarArchiveEntry.h * * @brief A class which represents a mutable entry of a tar archive. */ @interface OFMutableTarArchiveEntry: OFTarArchiveEntry { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutableTarArchiveEntry, 4) } -/*! +/** * @brief The file name of the entry. */ @property (readwrite, copy, nonatomic) OFString *fileName; -/*! +/** * @brief The mode of the entry. */ -@property (readwrite, nonatomic) uint32_t mode; +@property (readwrite, nonatomic) unsigned long mode; -/*! +/** * @brief The UID of the owner. */ -@property (readwrite, nonatomic) uint32_t UID; +@property (readwrite, nonatomic) unsigned long UID; -/*! +/** * @brief The GID of the group. */ -@property (readwrite, nonatomic) uint32_t GID; +@property (readwrite, nonatomic) unsigned long GID; -/*! +/** * @brief The size of the file. */ -@property (readwrite, nonatomic) uint64_t size; +@property (readwrite, nonatomic) unsigned long long size; -/*! +/** * @brief The date of the last modification of the file. */ @property (readwrite, retain, nonatomic) OFDate *modificationDate; -/*! +/** * @brief The type of the archive entry. * * See @ref of_tar_archive_entry_type_t. */ @property (readwrite, nonatomic) of_tar_archive_entry_type_t type; -/*! +/** * @brief The file name of the target (for a hard link or symbolic link). */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *targetFileName; -/*! +/** * @brief The owner of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *owner; -/*! +/** * @brief The group of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *group; -/*! +/** * @brief The device major (if the file is a device). */ -@property (readwrite, nonatomic) uint32_t deviceMajor; +@property (readwrite, nonatomic) unsigned long deviceMajor; -/*! +/** * @brief The device major (if the file is a device). */ -@property (readwrite, nonatomic) uint32_t deviceMinor; +@property (readwrite, nonatomic) unsigned long deviceMinor; -/*! +/** * @brief Converts the OFMutableTarArchiveEntry to an immutable * OFTarArchiveEntry. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END Index: src/OFMutableTarArchiveEntry.m ================================================================== --- src/OFMutableTarArchiveEntry.m +++ src/OFMutableTarArchiveEntry.m @@ -39,26 +39,26 @@ OFString *old = _fileName; _fileName = [fileName copy]; [old release]; } -- (void)setMode: (uint32_t)mode +- (void)setMode: (unsigned long)mode { _mode = mode; } -- (void)setUID: (uint32_t)UID +- (void)setUID: (unsigned long)UID { _UID = UID; } -- (void)setGID: (uint32_t)GID +- (void)setGID: (unsigned long)GID { _GID = GID; } -- (void)setSize: (uint64_t)size +- (void)setSize: (unsigned long long)size { _size = size; } - (void)setModificationDate: (OFDate *)modificationDate @@ -92,20 +92,20 @@ OFString *old = _group; _group = [group copy]; [old release]; } -- (void)setDeviceMajor: (uint32_t)deviceMajor +- (void)setDeviceMajor: (unsigned long)deviceMajor { _deviceMajor = deviceMajor; } -- (void)setDeviceMinor: (uint32_t)deviceMinor +- (void)setDeviceMinor: (unsigned long)deviceMinor { _deviceMinor = deviceMinor; } - (void)makeImmutable { object_setClass(self, [OFTarArchiveEntry class]); } @end Index: src/OFMutableTriple.h ================================================================== --- src/OFMutableTriple.h +++ src/OFMutableTriple.h @@ -17,11 +17,11 @@ #import "OFTriple.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutableTriple OFMutableTriple.h ObjFW/OFMutableTriple.h * * @brief A class for storing a triple of three objects. */ @interface OFMutableTriple OF_GENERIC(FirstType, SecondType, ThirdType): @@ -30,29 +30,29 @@ # define FirstType id # define SecondType id # define ThirdType id #endif { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutableTriple, 4) } -/*! +/** * @brief The first object of the triple. */ @property (readwrite, nonatomic, retain) FirstType firstObject; -/*! +/** * @brief The second object of the triple. */ @property (readwrite, nonatomic, retain) SecondType secondObject; -/*! +/** * @brief The third object of the triple. */ @property (readwrite, nonatomic, retain) ThirdType thirdObject; -/*! +/** * @brief Converts the mutable triple to an immutable triple. */ - (void)makeImmutable; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef FirstType Index: src/OFMutableURL.h ================================================================== --- src/OFMutableURL.h +++ src/OFMutableURL.h @@ -17,162 +17,176 @@ #import "OFURL.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutableURL OFMutableURL.h ObjFW/OFMutableURL.h * * @brief A class for parsing URLs and accessing parts of it. */ @interface OFMutableURL: OFURL { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutableURL, 4) } -/*! +/** * @brief The scheme part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *scheme; -/*! +/** * @brief The scheme part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedScheme; -/*! +/** * @brief The host part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *host; -/*! +/** * @brief The host part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedHost; -/*! +/** * @brief The port part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFNumber *port; -/*! +/** * @brief The user part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *user; -/*! +/** * @brief The user part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedUser; -/*! +/** * @brief The password part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *password; -/*! +/** * @brief The password part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedPassword; -/*! +/** * @brief The path part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *path; -/*! +/** * @brief The path part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedPath; -/*! +/** * @brief The path of the URL split into components. * * The first component must always be empty to designate the root. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFArray OF_GENERIC(OFString *) *pathComponents; -/*! +/** * @brief The query part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *query; -/*! +/** * @brief The query part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedQuery; -/*! +/** + * @brief The query part of the URL as a dictionary. + * + * For example, a query like `key1=value1&key2=value2` would correspond to the + * following dictionary: + * + * @{ + * @"key1": "value1", + * @"key2": "value2" + * } + */ +@property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) + OFDictionary OF_GENERIC(OFString *, OFString *) *queryDictionary; + +/** * @brief The fragment part of the URL. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *fragment; -/*! +/** * @brief The fragment part of the URL in URL-encoded form. * * Setting this retains the original URL-encoding used - if more characters * than necessary are URL-encoded, it is kept this way. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *URLEncodedFragment; -/*! +/** * @brief Creates a new mutable URL. * * @return A new, autoreleased OFMutableURL */ + (instancetype)URL; -/*! +/** * @brief Appends the specified path component. * * @param component The component to append */ - (void)appendPathComponent: (OFString *)component; -/*! +/** * @brief Appends the specified path component. * * @param component The component to append * @param isDirectory Whether the path is a directory, in which case a slash is * appened if there is no slash yet */ - (void)appendPathComponent: (OFString *)component isDirectory: (bool)isDirectory; -/*! +/** * @brief Resolves relative sub paths. */ - (void)standardizePath; -/*! +/** * @brief Converts the mutable URL to an immutable URL. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END Index: src/OFMutableURL.m ================================================================== --- src/OFMutableURL.m +++ src/OFMutableURL.m @@ -17,10 +17,11 @@ #include "config.h" #import "OFMutableURL.h" #import "OFArray.h" +#import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFileManager.h" #endif #import "OFNumber.h" #import "OFString.h" @@ -30,11 +31,12 @@ extern void of_url_verify_escaped(OFString *, OFCharacterSet *); @implementation OFMutableURL @dynamic scheme, URLEncodedScheme, host, URLEncodedHost, port, user; @dynamic URLEncodedUser, password, URLEncodedPassword, path, URLEncodedPath; -@dynamic pathComponents, query, URLEncodedQuery, fragment, URLEncodedFragment; +@dynamic pathComponents, query, URLEncodedQuery, queryDictionary, fragment; +@dynamic URLEncodedFragment; + (instancetype)URL { return [[[self alloc] init] autorelease]; } @@ -230,10 +232,51 @@ old = _URLEncodedQuery; _URLEncodedQuery = [URLEncodedQuery copy]; [old release]; } + +- (void)setQueryDictionary: + (OFDictionary OF_GENERIC(OFString *, OFString *) *)dictionary +{ + void *pool; + OFMutableString *URLEncodedQuery; + OFEnumerator OF_GENERIC(OFString *) *keyEnumerator, *objectEnumerator; + OFCharacterSet *characterSet; + OFString *key, *object, *old; + + if (dictionary == nil) { + [_URLEncodedQuery release]; + _URLEncodedQuery = nil; + return; + } + + pool = objc_autoreleasePoolPush(); + URLEncodedQuery = [OFMutableString string]; + keyEnumerator = [dictionary keyEnumerator]; + objectEnumerator = [dictionary objectEnumerator]; + characterSet = [OFCharacterSet URLQueryKeyValueAllowedCharacterSet]; + + while ((key = [keyEnumerator nextObject]) != nil && + (object = [objectEnumerator nextObject]) != nil) { + key = [key + stringByURLEncodingWithAllowedCharacters: characterSet]; + object = [object + stringByURLEncodingWithAllowedCharacters: characterSet]; + + if (URLEncodedQuery.length > 0) + [URLEncodedQuery appendString: @"&"]; + + [URLEncodedQuery appendFormat: @"%@=%@", key, object]; + } + + old = _URLEncodedQuery; + _URLEncodedQuery = [URLEncodedQuery copy]; + [old release]; + + objc_autoreleasePoolPop(pool); +} - (void)setFragment: (OFString *)fragment { void *pool = objc_autoreleasePoolPush(); OFString *old = _URLEncodedFragment; Index: src/OFMutableZIPArchiveEntry.h ================================================================== --- src/OFMutableZIPArchiveEntry.h +++ src/OFMutableZIPArchiveEntry.h @@ -17,66 +17,66 @@ #import "OFZIPArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutableZIPArchiveEntry \ * OFMutableZIPArchiveEntry.h ObjFW/OFMutableZIPArchiveEntry.h * * @brief A class which represents a mutable entry in the central directory of * a ZIP archive. */ @interface OFMutableZIPArchiveEntry: OFZIPArchiveEntry { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutableZIPArchiveEntry, 4) } -/*! +/** * @brief The file name of the entry. */ @property (readwrite, copy, nonatomic) OFString *fileName; -/*! +/** * @brief The comment of the entry's file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *fileComment; -/*! +/** * @brief The extra field of the entry. * * The item size *must* be 1! */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFData *extraField; -/*! +/** * @brief The version which made the entry. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref of_zip_archive_entry_attribute_compatibility. */ @property (readwrite, nonatomic) uint16_t versionMadeBy; -/*! +/** * @brief The minimum version required to extract the file. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref of_zip_archive_entry_attribute_compatibility. */ @property (readwrite, nonatomic) uint16_t minVersionNeeded; -/*! +/** * @brief The last modification date of the entry's file. * * @note Due to limitations of the ZIP format, this has only 2 second precision. */ @property (readwrite, retain, nonatomic) OFDate *modificationDate; -/*! +/** * @brief The compression method of the entry. * * Supported values are: * Value | Description * --------------------------------------------------|--------------- @@ -86,43 +86,43 @@ * * Other values may be returned, but the file cannot be extracted then. */ @property (readwrite, nonatomic) uint16_t compressionMethod; -/*! +/** * @brief The compressed size of the entry's file. */ @property (readwrite, nonatomic) uint64_t compressedSize; -/*! +/** * @brief The uncompressed size of the entry's file. */ @property (readwrite, nonatomic) uint64_t uncompressedSize; -/*! +/** * @brief The CRC32 checksum of the entry's file. */ @property (readwrite, nonatomic) uint32_t CRC32; -/*! +/** * @brief The version specific attributes. * * The meaning of the version specific attributes depends on the attribute * compatibility part of the version that made the entry. */ @property (readwrite, nonatomic) uint32_t versionSpecificAttributes; -/*! +/** * @brief The general purpose bit flag of the entry. * * See the ZIP specification for details. */ @property (readwrite, nonatomic) uint16_t generalPurposeBitFlag; -/*! +/** * @brief Converts the OFMutableZIPArchiveEntry to an immutable * OFZIPArchiveEntry. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END Index: src/OFMutex.h ================================================================== --- src/OFMutex.h +++ src/OFMutex.h @@ -20,27 +20,27 @@ #import "mutex.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMutex OFMutex.h ObjFW/OFMutex.h * * @brief A class for creating mutual exclusions. */ @interface OFMutex: OFObject { of_mutex_t _mutex; bool _initialized; OFString *_Nullable _name; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFMutex, 4) } -/*! +/** * @brief Creates a new mutex. * * @return A new autoreleased mutex. */ + (instancetype)mutex; @end OF_ASSUME_NONNULL_END Index: src/OFNull.h ================================================================== --- src/OFNull.h +++ src/OFNull.h @@ -21,22 +21,22 @@ #import "OFMessagePackRepresentation.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFNull OFNull.h ObjFW/OFNull.h * * @brief A class for representing null values in collections. */ OF_SUBCLASSING_RESTRICTED @interface OFNull: OFObject -/*! +/** * @brief Returns an OFNull singleton. * * @return An OFNull singleton */ + (OFNull *)null; @end OF_ASSUME_NONNULL_END Index: src/OFNumber.h ================================================================== --- src/OFNumber.h +++ src/OFNumber.h @@ -33,274 +33,97 @@ #import "OFSerialization.h" #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ - -/*! - * @brief The C type of a number stored in an OFNumber. - */ -typedef enum { - /*! `bool` */ - OF_NUMBER_TYPE_BOOL = 0x01, - /*! `unsigned char` */ - OF_NUMBER_TYPE_UCHAR = 0x02, - /*! `unsigned short` */ - OF_NUMBER_TYPE_USHORT = 0x03, - /*! `unsigned int` */ - OF_NUMBER_TYPE_UINT = 0x04, - /*! `unsigned long` */ - OF_NUMBER_TYPE_ULONG = 0x05, - /*! `unsigned long long` */ - OF_NUMBER_TYPE_ULONGLONG = 0x06, - /*! `size_t` */ - OF_NUMBER_TYPE_SIZE = 0x07, - /*! `uint8_t` */ - OF_NUMBER_TYPE_UINT8 = 0x08, - /*! `uint16_t` */ - OF_NUMBER_TYPE_UINT16 = 0x09, - /*! `uint32_t` */ - OF_NUMBER_TYPE_UINT32 = 0x0A, - /*! `uint64_t` */ - OF_NUMBER_TYPE_UINT64 = 0x0B, - /*! `uintptr_t` */ - OF_NUMBER_TYPE_UINTPTR = 0x0C, - /*! `uintmax_t` */ - OF_NUMBER_TYPE_UINTMAX = 0x0D, - OF_NUMBER_TYPE_SIGNED = 0x10, - /*! `signed char` */ - OF_NUMBER_TYPE_CHAR = OF_NUMBER_TYPE_UCHAR | - OF_NUMBER_TYPE_SIGNED, - /*! `signed short` */ - OF_NUMBER_TYPE_SHORT = OF_NUMBER_TYPE_USHORT | - OF_NUMBER_TYPE_SIGNED, - /*! `signed int` */ - OF_NUMBER_TYPE_INT = OF_NUMBER_TYPE_UINT | - OF_NUMBER_TYPE_SIGNED, - /*! `signed long` */ - OF_NUMBER_TYPE_LONG = OF_NUMBER_TYPE_ULONG | - OF_NUMBER_TYPE_SIGNED, - /*! `signed long long` */ - OF_NUMBER_TYPE_LONGLONG = OF_NUMBER_TYPE_ULONGLONG | - OF_NUMBER_TYPE_SIGNED, - /*! `int8_t` */ - OF_NUMBER_TYPE_INT8 = OF_NUMBER_TYPE_UINT8 | - OF_NUMBER_TYPE_SIGNED, - /*! `int16_t` */ - OF_NUMBER_TYPE_INT16 = OF_NUMBER_TYPE_UINT16 | - OF_NUMBER_TYPE_SIGNED, - /*! `int32_t` */ - OF_NUMBER_TYPE_INT32 = OF_NUMBER_TYPE_UINT32 | - OF_NUMBER_TYPE_SIGNED, - /*! `int64_t` */ - OF_NUMBER_TYPE_INT64 = OF_NUMBER_TYPE_UINT64 | - OF_NUMBER_TYPE_SIGNED, - /*! `ssize_t` */ - OF_NUMBER_TYPE_SSIZE = OF_NUMBER_TYPE_SIZE | - OF_NUMBER_TYPE_SIGNED, - /*! `intmax_t` */ - OF_NUMBER_TYPE_INTMAX = OF_NUMBER_TYPE_UINTMAX | - OF_NUMBER_TYPE_SIGNED, - /*! `ptrdiff_t` */ - OF_NUMBER_TYPE_PTRDIFF = 0x0E | OF_NUMBER_TYPE_SIGNED, - /*! `intptr_t` */ - OF_NUMBER_TYPE_INTPTR = 0x0F | OF_NUMBER_TYPE_SIGNED, - /*! `float` */ - OF_NUMBER_TYPE_FLOAT = 0x20, - /*! `double` */ - OF_NUMBER_TYPE_DOUBLE = 0x40 | OF_NUMBER_TYPE_FLOAT -} of_number_type_t; - -/*! +/** @file */ + +/** * @class OFNumber OFNumber.h ObjFW/OFNumber.h * * @brief Provides a way to store a number in an object. */ +#ifndef OF_NUMBER_M OF_SUBCLASSING_RESTRICTED +#endif @interface OFNumber: OFValue { union of_number_value { - bool bool_; - signed char sChar; - signed short sShort; - signed int sInt; - signed long sLong; - signed long long sLongLong; - unsigned char uChar; - unsigned short uShort; - unsigned int uInt; - unsigned long uLong; - unsigned long long uLongLong; - int8_t int8; - int16_t int16; - int32_t int32; - int64_t int64; - uint8_t uInt8; - uint16_t uInt16; - uint32_t uInt32; - uint64_t uInt64; - size_t size; - ssize_t sSize; - intmax_t intMax; - uintmax_t uIntMax; - ptrdiff_t ptrDiff; - intptr_t intPtr; - uintptr_t uIntPtr; - float float_; - double double_; - } _value; - of_number_type_t _type; -} - -/*! - * @brief The type of the number. - */ -@property (readonly, nonatomic) of_number_type_t type; - -/*! + double float_; + long long signed_; + unsigned long long unsigned_; + } _value; + const char *_typeEncoding; +} + +/** * @brief The OFNumber as a `bool`. */ @property (readonly, nonatomic) bool boolValue; -/*! +/** * @brief The OFNumber as a `signed char`. */ @property (readonly, nonatomic) signed char charValue; -/*! - * @brief The OFNumber as a `signed short`. - */ -@property (readonly, nonatomic) signed short shortValue; - -/*! - * @brief The OFNumber as a `signed int`. - */ -@property (readonly, nonatomic) signed int intValue; - -/*! - * @brief The OFNumber as a `signed long`. - */ -@property (readonly, nonatomic) signed long longValue; - -/*! - * @brief The OFNumber as a `signed long long`. - */ -@property (readonly, nonatomic) signed long long longLongValue; - -/*! +/** + * @brief The OFNumber as a `short`. + */ +@property (readonly, nonatomic) short shortValue; + +/** + * @brief The OFNumber as an `int`. + */ +@property (readonly, nonatomic) int intValue; + +/** + * @brief The OFNumber as a `long`. + */ +@property (readonly, nonatomic) long longValue; + +/** + * @brief The OFNumber as a `long long`. + */ +@property (readonly, nonatomic) long long longLongValue; + +/** * @brief The OFNumber as an `unsigned char`. */ @property (readonly, nonatomic) unsigned char unsignedCharValue; -/*! +/** * @brief The OFNumber as an `unsigned short`. */ @property (readonly, nonatomic) unsigned short unsignedShortValue; -/*! +/** * @brief The OFNumber as an `unsigned int`. */ @property (readonly, nonatomic) unsigned int unsignedIntValue; -/*! +/** * @brief The OFNumber as an `unsigned long`. */ @property (readonly, nonatomic) unsigned long unsignedLongValue; -/*! +/** * @brief The OFNumber as an `unsigned long long`. */ @property (readonly, nonatomic) unsigned long long unsignedLongLongValue; -/*! - * @brief The OFNumber as an `int8_t`. - */ -@property (readonly, nonatomic) int8_t int8Value; - -/*! - * @brief The OFNumber as an `int16_t`. - */ -@property (readonly, nonatomic) int16_t int16Value; - -/*! - * @brief The OFNumber as an `int32_t`. - */ -@property (readonly, nonatomic) int32_t int32Value; - -/*! - * @brief The OFNumber as an `int64_t`. - */ -@property (readonly, nonatomic) int64_t int64Value; - -/*! - * @brief The OFNumber as a `uint8_t`. - */ -@property (readonly, nonatomic) uint8_t uInt8Value; - -/*! - * @brief The OFNumber as a `uint16_t`. - */ -@property (readonly, nonatomic) uint16_t uInt16Value; - -/*! - * @brief The OFNumber as a `uint32_t`. - */ -@property (readonly, nonatomic) uint32_t uInt32Value; - -/*! - * @brief The OFNumber as a `uint64_t`. - */ -@property (readonly, nonatomic) uint64_t uInt64Value; - -/*! - * @brief The OFNumber as a `size_t`. - */ -@property (readonly, nonatomic) size_t sizeValue; - -/*! - * @brief The OFNumber as an `ssize_t`. - */ -@property (readonly, nonatomic) ssize_t sSizeValue; - -/*! - * @brief The OFNumber as an `intmax_t`. - */ -@property (readonly, nonatomic) intmax_t intMaxValue; - -/*! - * @brief The OFNumber as a `uintmax_t`. - */ -@property (readonly, nonatomic) uintmax_t uIntMaxValue; - -/*! - * @brief The OFNumber as a `ptrdiff_t`. - */ -@property (readonly, nonatomic) ptrdiff_t ptrDiffValue; - -/*! - * @brief The OFNumber as an `intptr_t`. - */ -@property (readonly, nonatomic) intptr_t intPtrValue; - -/*! - * @brief The OFNumber as a `uintptr_t`. - */ -@property (readonly, nonatomic) uintptr_t uIntPtrValue; - -/*! +/** * @brief The OFNumber as a `float`. */ @property (readonly, nonatomic) float floatValue; -/*! +/** * @brief The OFNumber as a `double`. */ @property (readonly, nonatomic) double doubleValue; -/*! +/** * @brief The OFNumber as a string. */ @property (readonly, nonatomic) OFString *stringValue; #ifdef OF_HAVE_UNAVAILABLE @@ -312,233 +135,113 @@ + (instancetype)valueWithPoint: (of_point_t)point OF_UNAVAILABLE; + (instancetype)valueWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE; + (instancetype)valueWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE; #endif -/*! - * @brief Creates a new OFNumber with the specified `bool`. - * - * @param bool_ A `bool` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithBool: (bool)bool_; - -/*! - * @brief Creates a new OFNumber with the specified `signed char`. - * - * @param sChar A `signed char` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithChar: (signed char)sChar; - -/*! - * @brief Creates a new OFNumber with the specified `signed short`. - * - * @param sShort A `signed short` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithShort: (signed short)sShort; - -/*! - * @brief Creates a new OFNumber with the specified `signed int`. - * - * @param sInt A `signed int` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithInt: (signed int)sInt; - -/*! - * @brief Creates a new OFNumber with the specified `signed long`. - * - * @param sLong A `signed long` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithLong: (signed long)sLong; - -/*! - * @brief Creates a new OFNumber with the specified `signed long long`. - * - * @param sLongLong A `signed long long` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithLongLong: (signed long long)sLongLong; - -/*! - * @brief Creates a new OFNumber with the specified `unsigned char`. - * - * @param uChar An `unsigned char` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUnsignedChar: (unsigned char)uChar; - -/*! - * @brief Creates a new OFNumber with the specified `unsigned short`. - * - * @param uShort An `unsigned short` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUnsignedShort: (unsigned short)uShort; - -/*! - * @brief Creates a new OFNumber with the specified `unsigned int`. - * - * @param uInt An `unsigned int` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUnsignedInt: (unsigned int)uInt; - -/*! - * @brief Creates a new OFNumber with the specified `unsigned long`. - * - * @param uLong An `unsigned long` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUnsignedLong: (unsigned long)uLong; - -/*! - * @brief Creates a new OFNumber with the specified `unsigned long long`. - * - * @param uLongLong An `unsigned long long` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)uLongLong; - -/*! - * @brief Creates a new OFNumber with the specified `int8_t`. - * - * @param int8 An `int8_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithInt8: (int8_t)int8; - -/*! - * @brief Creates a new OFNumber with the specified `int16_t`. - * - * @param int16 An `int16_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithInt16: (int16_t)int16; - -/*! - * @brief Creates a new OFNumber with the specified `int32_t`. - * - * @param int32 An `int32_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithInt32: (int32_t)int32; - -/*! - * @brief Creates a new OFNumber with the specified `int64_t`. - * - * @param int64 An `int64_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithInt64: (int64_t)int64; - -/*! - * @brief Creates a new OFNumber with the specified `uint8_t`. - * - * @param uInt8 A `uint8_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUInt8: (uint8_t)uInt8; - -/*! - * @brief Creates a new OFNumber with the specified `uint16_t`. - * - * @param uInt16 A `uint16_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUInt16: (uint16_t)uInt16; - -/*! - * @brief Creates a new OFNumber with the specified `uint32_t`. - * - * @param uInt32 A `uint32_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUInt32: (uint32_t)uInt32; - -/*! - * @brief Creates a new OFNumber with the specified `uint64_t`. - * - * @param uInt64 A `uint64_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUInt64: (uint64_t)uInt64; - -/*! - * @brief Creates a new OFNumber with the specified `size_t`. - * - * @param size A `size_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithSize: (size_t)size; - -/*! - * @brief Creates a new OFNumber with the specified `ssize_t`. - * - * @param sSize An `ssize_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithSSize: (ssize_t)sSize; - -/*! - * @brief Creates a new OFNumber with the specified `intmax_t`. - * - * @param intMax An `intmax_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithIntMax: (intmax_t)intMax; - -/*! - * @brief Creates a new OFNumber with the specified `uintmax_t`. - * - * @param uIntMax A `uintmax_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUIntMax: (uintmax_t)uIntMax; - -/*! - * @brief Creates a new OFNumber with the specified `ptrdiff_t`. - * - * @param ptrDiff A `ptrdiff_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithPtrDiff: (ptrdiff_t)ptrDiff; - -/*! - * @brief Creates a new OFNumber with the specified `intptr_t`. - * - * @param intPtr An `intptr_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithIntPtr: (intptr_t)intPtr; - -/*! - * @brief Creates a new OFNumber with the specified `uintptr_t`. - * - * @param uIntPtr A `uintptr_t` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithUIntPtr: (uintptr_t)uIntPtr; - -/*! - * @brief Creates a new OFNumber with the specified `float`. - * - * @param float_ A `float` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithFloat: (float)float_; - -/*! - * @brief Creates a new OFNumber with the specified `double`. - * - * @param double_ A `double` which the OFNumber should contain - * @return A new autoreleased OFNumber - */ -+ (instancetype)numberWithDouble: (double)double_; +/** + * @brief Creates a new OFNumber with the specified `bool`. + * + * @param value The `bool` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithBool: (bool)value; + +/** + * @brief Creates a new OFNumber with the specified `signed char`. + * + * @param value The `signed char` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithChar: (signed char)value; + +/** + * @brief Creates a new OFNumber with the specified `short`. + * + * @param value The `short` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithShort: (short)value; + +/** + * @brief Creates a new OFNumber with the specified `int`. + * + * @param value The `int` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithInt: (int)value; + +/** + * @brief Creates a new OFNumber with the specified `long`. + * + * @param value The `long` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithLong: (long)value; + +/** + * @brief Creates a new OFNumber with the specified `long long`. + * + * @param value The `long long` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithLongLong: (long long)value; + +/** + * @brief Creates a new OFNumber with the specified `unsigned char`. + * + * @param value The `unsigned char` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithUnsignedChar: (unsigned char)value; + +/** + * @brief Creates a new OFNumber with the specified `unsigned short`. + * + * @param value The `unsigned short` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithUnsignedShort: (unsigned short)value; + +/** + * @brief Creates a new OFNumber with the specified `unsigned int`. + * + * @param value The `unsigned int` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithUnsignedInt: (unsigned int)value; + +/** + * @brief Creates a new OFNumber with the specified `unsigned long`. + * + * @param value The `unsigned long` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithUnsignedLong: (unsigned long)value; + +/** + * @brief Creates a new OFNumber with the specified `unsigned long long`. + * + * @param value The `unsigned long long` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithUnsignedLongLong: (unsigned long long)value; + +/** + * @brief Creates a new OFNumber with the specified `float`. + * + * @param value The `float` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithFloat: (float)value; + +/** + * @brief Creates a new OFNumber with the specified `double`. + * + * @param value The `double` value which the OFNumber should contain + * @return A new autoreleased OFNumber + */ ++ (instancetype)numberWithDouble: (double)value; - (instancetype)init OF_UNAVAILABLE; #ifdef OF_HAVE_UNAVAILABLE - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType OF_UNAVAILABLE; @@ -548,259 +251,123 @@ - (instancetype)initWithPoint: (of_point_t)point OF_UNAVAILABLE; - (instancetype)initWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE; - (instancetype)initWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE; #endif -/*! +/** * @brief Initializes an already allocated OFNumber with the specified `bool`. * - * @param bool_ A `bool` which the OFNumber should contain + * @param value The `bool` value which the OFNumber should contain * @return An initialized OFNumber */ -- (instancetype)initWithBool: (bool)bool_; +- (instancetype)initWithBool: (bool)value; -/*! +/** * @brief Initializes an already allocated OFNumber with the specified * `signed char`. * - * @param sChar A `signed char` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithChar: (signed char)sChar; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `signed short`. - * - * @param sShort A `signed short` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithShort: (signed short)sShort; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `signed int`. - * - * @param sInt A `signed int` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithInt: (signed int)sInt; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `signed long`. - * - * @param sLong A `signed long` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithLong: (signed long)sLong; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `signed long long`. - * - * @param sLongLong A `signed long long` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithLongLong: (signed long long)sLongLong; - -/*! + * @param value The `signed char` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithChar: (signed char)value; + +/** + * @brief Initializes an already allocated OFNumber with the specified `short`. + * + * @param value The `short` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithShort: (short)value; + +/** + * @brief Initializes an already allocated OFNumber with the specified `int`. + * + * @param value The `int` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithInt: (int)value; + +/** + * @brief Initializes an already allocated OFNumber with the specified `long`. + * + * @param value The `long` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithLong: (long)value; + +/** + * @brief Initializes an already allocated OFNumber with the specified + * `long long`. + * + * @param value The `long long` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithLongLong: (long long)value; + +/** * @brief Initializes an already allocated OFNumber with the specified * `unsigned char`. * - * @param uChar An `unsigned char` which the OFNumber should contain + * @param value The `unsigned char` value which the OFNumber should contain * @return An initialized OFNumber */ -- (instancetype)initWithUnsignedChar: (unsigned char)uChar; +- (instancetype)initWithUnsignedChar: (unsigned char)value; -/*! +/** * @brief Initializes an already allocated OFNumber with the specified * `unsigned short`. * - * @param uShort An `unsigned short` which the OFNumber should contain + * @param value The `unsigned short` value which the OFNumber should contain * @return An initialized OFNumber */ -- (instancetype)initWithUnsignedShort: (unsigned short)uShort; +- (instancetype)initWithUnsignedShort: (unsigned short)value; -/*! +/** * @brief Initializes an already allocated OFNumber with the specified * `unsigned int`. * - * @param uInt An `unsigned int` which the OFNumber should contain + * @param value The `unsigned int` value which the OFNumber should contain * @return An initialized OFNumber */ -- (instancetype)initWithUnsignedInt: (unsigned int)uInt; +- (instancetype)initWithUnsignedInt: (unsigned int)value; -/*! +/** * @brief Initializes an already allocated OFNumber with the specified * `unsigned long`. * - * @param uLong An `unsigned long` which the OFNumber should contain + * @param value The `unsigned long` value which the OFNumber should contain * @return An initialized OFNumber */ -- (instancetype)initWithUnsignedLong: (unsigned long)uLong; +- (instancetype)initWithUnsignedLong: (unsigned long)value; -/*! +/** * @brief Initializes an already allocated OFNumber with the specified * `unsigned long long`. * - * @param uLongLong An `unsigned long long` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong; - -/*! - * @brief Initializes an already allocated OFNumber with the specified `int8_t`. - * - * @param int8 An `int8_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithInt8: (int8_t)int8; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `int16_t`. - * - * @param int16 An `int16_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithInt16: (int16_t)int16; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `int32_t`. - * - * @param int32 An `int32_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithInt32: (int32_t)int32; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `int64_t`. - * - * @param int64 An `int64_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithInt64: (int64_t)int64; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `uint8_t`. - * - * @param uInt8 A `uint8_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUInt8: (uint8_t)uInt8; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `uint16_t`. - * - * @param uInt16 A `uint16_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUInt16: (uint16_t)uInt16; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `uint32_t`. - * - * @param uInt32 A `uint32_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUInt32: (uint32_t)uInt32; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `uint64_t`. - * - * @param uInt64 A `uint64_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUInt64: (uint64_t)uInt64; - -/*! - * @brief Initializes an already allocated OFNumber with the specified `size_t`. - * - * @param size A `size_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithSize: (size_t)size; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `ssize_t`. - * - * @param sSize An `ssize_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithSSize: (ssize_t)sSize; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `intmax_t`. - * - * @param intMax An `intmax_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithIntMax: (intmax_t)intMax; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `uintmax_t`. - * - * @param uIntMax A `uintmax_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUIntMax: (uintmax_t)uIntMax; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `ptrdiff_t`. - * - * @param ptrDiff A `ptrdiff_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `intptr_t`. - * - * @param intPtr An `intptr_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithIntPtr: (intptr_t)intPtr; - -/*! - * @brief Initializes an already allocated OFNumber with the specified - * `uintptr_t`. - * - * @param uIntPtr A `uintptr_t` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr; - -/*! - * @brief Initializes an already allocated OFNumber with the specified `float`. - * - * @param float_ A `float` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithFloat: (float)float_; - -/*! - * @brief Initializes an already allocated OFNumber with the specified `double`. - * - * @param double_ A `double` which the OFNumber should contain - * @return An initialized OFNumber - */ -- (instancetype)initWithDouble: (double)double_; + * @param value The `unsigned long long` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithUnsignedLongLong: (unsigned long long)value; + +/** + * @brief Initializes an already allocated OFNumber with the specified `float`. + * + * @param value The `float` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithFloat: (float)value; + +/** + * @brief Initializes an already allocated OFNumber with the specified `double`. + * + * @param value The `double` value which the OFNumber should contain + * @return An initialized OFNumber + */ +- (instancetype)initWithDouble: (double)value; @end OF_ASSUME_NONNULL_END #if !defined(NSINTEGER_DEFINED) && !__has_feature(modules) /* Required for number literals to work */ @compatibility_alias NSNumber OFNumber; #endif Index: src/OFNumber.m ================================================================== --- src/OFNumber.m +++ src/OFNumber.m @@ -13,10 +13,12 @@ * 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. */ +#define OF_NUMBER_M + #include "config.h" #include #import "OFNumber.h" @@ -27,501 +29,718 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" -#define RETURN_AS(t) \ - switch (_type) { \ - case OF_NUMBER_TYPE_BOOL: \ - return (t)_value.bool_; \ - case OF_NUMBER_TYPE_CHAR: \ - return (t)_value.sChar; \ - case OF_NUMBER_TYPE_SHORT: \ - return (t)_value.sShort; \ - case OF_NUMBER_TYPE_INT: \ - return (t)_value.sInt; \ - case OF_NUMBER_TYPE_LONG: \ - return (t)_value.sLong; \ - case OF_NUMBER_TYPE_LONGLONG: \ - return (t)_value.sLongLong; \ - case OF_NUMBER_TYPE_UCHAR: \ - return (t)_value.uChar; \ - case OF_NUMBER_TYPE_USHORT: \ - return (t)_value.uShort; \ - case OF_NUMBER_TYPE_UINT: \ - return (t)_value.uInt; \ - case OF_NUMBER_TYPE_ULONG: \ - return (t)_value.uLong; \ - case OF_NUMBER_TYPE_ULONGLONG: \ - return (t)_value.uLongLong; \ - case OF_NUMBER_TYPE_INT8: \ - return (t)_value.int8; \ - case OF_NUMBER_TYPE_INT16: \ - return (t)_value.int16; \ - case OF_NUMBER_TYPE_INT32: \ - return (t)_value.int32; \ - case OF_NUMBER_TYPE_INT64: \ - return (t)_value.int64; \ - case OF_NUMBER_TYPE_UINT8: \ - return (t)_value.uInt8; \ - case OF_NUMBER_TYPE_UINT16: \ - return (t)_value.uInt16; \ - case OF_NUMBER_TYPE_UINT32: \ - return (t)_value.uInt32; \ - case OF_NUMBER_TYPE_UINT64: \ - return (t)_value.uInt64; \ - case OF_NUMBER_TYPE_SIZE: \ - return (t)_value.size; \ - case OF_NUMBER_TYPE_SSIZE: \ - return (t)_value.sSize; \ - case OF_NUMBER_TYPE_INTMAX: \ - return (t)_value.intMax; \ - case OF_NUMBER_TYPE_UINTMAX: \ - return (t)_value.uIntMax; \ - case OF_NUMBER_TYPE_PTRDIFF: \ - return (t)_value.ptrDiff; \ - case OF_NUMBER_TYPE_INTPTR: \ - return (t)_value.intPtr; \ - case OF_NUMBER_TYPE_UINTPTR: \ - return (t)_value.uIntPtr; \ - case OF_NUMBER_TYPE_FLOAT: \ - return (t)_value.float_; \ - case OF_NUMBER_TYPE_DOUBLE: \ - return (t)_value.double_; \ - default: \ - @throw [OFInvalidFormatException exception]; \ - } - @interface OFNumber () ++ (instancetype)of_alloc; - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth; @end + +@interface OFNumberPlaceholder: OFNumber +@end + +@interface OFNumberSingleton: OFNumber +@end + +#ifdef OF_OBJFW_RUNTIME +enum { + TAG_CHAR, + TAG_SHORT, + TAG_INT, + TAG_LONG, + TAG_LONG_LONG, + TAG_UNSIGNED_CHAR, + TAG_UNSIGNED_SHORT, + TAG_UNSIGNED_INT, + TAG_UNSIGNED_LONG, + TAG_UNSIGNED_LONG_LONG, +}; +# define TAG_BITS 4 +# define TAG_MASK 0xF + +@interface OFTaggedPointerNumber: OFNumberSingleton +@end +#endif + +static struct { + Class isa; +} placeholder; + +#define SINGLETON(var, sel, val) \ + static OFNumberSingleton *var; \ + \ + static void \ + var##Init(void) \ + { \ + var = [[OFNumberSingleton alloc] sel val]; \ + } +SINGLETON(falseNumber, initWithBool:, false) +SINGLETON(trueNumber, initWithBool:, true) +SINGLETON(charZeroNumber, initWithChar:, 0) +SINGLETON(shortZeroNumber, initWithShort:, 0) +SINGLETON(intZeroNumber, initWithInt:, 0) +SINGLETON(longZeroNumber, initWithLong:, 0) +SINGLETON(longLongZeroNumber, initWithLongLong:, 0) +SINGLETON(unsignedCharZeroNumber, initWithUnsignedChar:, 0) +SINGLETON(unsignedShortZeroNumber, initWithUnsignedShort:, 0) +SINGLETON(unsignedIntZeroNumber, initWithUnsignedInt:, 0) +SINGLETON(unsignedLongZeroNumber, initWithUnsignedLong:, 0) +SINGLETON(unsignedLongLongZeroNumber, initWithUnsignedLongLong:, 0) +SINGLETON(floatZeroNumber, initWithFloat:, 0) +SINGLETON(doubleZeroNumber, initWithDouble:, 0) +#undef SINGLETON + +#ifdef OF_OBJFW_RUNTIME +static int numberTag; +#endif + +static bool +isUnsigned(OFNumber *number) +{ + switch (*number.objCType) { + case 'B': + return true; + case 'C': + return true; + case 'S': + return true; + case 'I': + return true; + case 'L': + return true; + case 'Q': + return true; + default: + return false; + } +} + +static bool +isSigned(OFNumber *number) +{ + switch (*number.objCType) { + case 'c': + return true; + case 's': + return true; + case 'i': + return true; + case 'l': + return true; + case 'q': + return true; + default: + return false; + } +} + +static bool +isFloat(OFNumber *number) +{ + switch (*number.objCType) { + case 'f': + return true; + case 'd': + return true; + default: + return false; + } +} + +@implementation OFNumberPlaceholder +- (instancetype)initWithBool: (bool)value +{ + if (value) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, trueNumberInit); + return (id)trueNumber; + } else { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, falseNumberInit); + return (id)falseNumber; + } +} + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif +- (instancetype)initWithChar: (signed char)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, charZeroNumberInit); + return (id)charZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if ((unsigned char)value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)(unsigned char)value << TAG_BITS) | TAG_CHAR); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithChar: value]; +} + +- (instancetype)initWithShort: (short)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, shortZeroNumberInit); + return (id)shortZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if ((unsigned short)value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)(unsigned short)value << TAG_BITS) | TAG_SHORT); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithShort: value]; +} + +- (instancetype)initWithInt: (int)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, intZeroNumberInit); + return (id)intZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if ((unsigned int)value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)(unsigned int)value << TAG_BITS) | TAG_INT); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithInt: value]; +} + +- (instancetype)initWithLong: (long)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, longZeroNumberInit); + return (id)longZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if ((unsigned long)value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)(unsigned long)value << TAG_BITS) | TAG_LONG); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithLong: value]; +} + +- (instancetype)initWithLongLong: (long long)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, longLongZeroNumberInit); + return (id)longLongZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if ((unsigned long long)value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)(unsigned long long)value << TAG_BITS) | + TAG_LONG_LONG); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithLongLong: value]; +} + +- (instancetype)initWithUnsignedChar: (unsigned char)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, unsignedCharZeroNumberInit); + return (id)unsignedCharZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if (value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)value << TAG_BITS) | TAG_UNSIGNED_CHAR); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithUnsignedChar: value]; +} + +- (instancetype)initWithUnsignedShort: (unsigned short)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, unsignedShortZeroNumberInit); + return (id)unsignedShortZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if (value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)value << TAG_BITS) | TAG_UNSIGNED_SHORT); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithUnsignedShort: value]; +} + +- (instancetype)initWithUnsignedInt: (unsigned int)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, unsignedIntZeroNumberInit); + return (id)unsignedIntZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if (value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)value << TAG_BITS) | TAG_UNSIGNED_INT); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithUnsignedInt: value]; +} + +- (instancetype)initWithUnsignedLong: (unsigned long)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, unsignedLongZeroNumberInit); + return (id)unsignedLongZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if (value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)value << TAG_BITS) | TAG_UNSIGNED_LONG); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithUnsignedLong: value]; +} + +- (instancetype)initWithUnsignedLongLong: (unsigned long long)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, unsignedLongLongZeroNumberInit); + return (id)unsignedLongLongZeroNumber; +#ifdef OF_OBJFW_RUNTIME + } else if (value <= (UINTPTR_MAX >> TAG_BITS)) { + id ret = objc_createTaggedPointer(numberTag, + ((uintptr_t)value << TAG_BITS) | TAG_UNSIGNED_LONG_LONG); + + if (ret != nil) + return ret; +#endif + } + + return (id)[[OFNumber of_alloc] initWithUnsignedLongLong: value]; +} + +- (instancetype)initWithFloat: (float)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, floatZeroNumberInit); + return (id)floatZeroNumber; + } + + return (id)[[OFNumber of_alloc] initWithFloat: value]; +} + +- (instancetype)initWithDouble: (double)value +{ + if (value == 0) { + static of_once_t once = OF_ONCE_INIT; + of_once(&once, doubleZeroNumberInit); + return (id)doubleZeroNumber; + } + + return (id)[[OFNumber of_alloc] initWithDouble: value]; +} + +- (instancetype)initWithSerialization: (OFXMLElement *)element +{ + return (id)[[OFNumber of_alloc] initWithSerialization: element]; +} +#ifdef __clang__ +# pragma clang diagnostic pop +#endif +@end + +@implementation OFNumberSingleton +- (instancetype)autorelease +{ + return self; +} + +- (instancetype)retain +{ + return self; +} + +- (void)release +{ +} + +- (unsigned int)retainCount +{ + return OF_RETAIN_COUNT_MAX; +} +@end + +#ifdef OF_OBJFW_RUNTIME +@implementation OFTaggedPointerNumber +- (const char *)objCType +{ + uintptr_t value = object_getTaggedPointerValue(self); + + switch (value & TAG_MASK) { + case TAG_CHAR: + return @encode(signed char); + case TAG_SHORT: + return @encode(short); + case TAG_INT: + return @encode(int); + case TAG_LONG: + return @encode(long); + case TAG_LONG_LONG: + return @encode(long long); + case TAG_UNSIGNED_CHAR: + return @encode(unsigned char); + case TAG_UNSIGNED_SHORT: + return @encode(unsigned short); + case TAG_UNSIGNED_INT: + return @encode(unsigned int); + case TAG_UNSIGNED_LONG: + return @encode(unsigned long); + case TAG_UNSIGNED_LONG_LONG: + return @encode(unsigned long long); + default: + @throw [OFInvalidArgumentException exception]; + } +} + +# define RETURN_VALUE \ + uintptr_t value = object_getTaggedPointerValue(self); \ + \ + switch (value & TAG_MASK) { \ + case TAG_CHAR: \ + return (signed char)(unsigned char)(value >> TAG_BITS); \ + case TAG_SHORT: \ + return (short)(unsigned short)(value >> TAG_BITS); \ + case TAG_INT: \ + return (int)(unsigned int)(value >> TAG_BITS); \ + case TAG_LONG: \ + return (long)(unsigned long)(value >> TAG_BITS); \ + case TAG_LONG_LONG: \ + return (long long)(unsigned long long)(value >> TAG_BITS); \ + case TAG_UNSIGNED_CHAR: \ + return (unsigned char)(value >> TAG_BITS); \ + case TAG_UNSIGNED_SHORT: \ + return (unsigned short)(value >> TAG_BITS); \ + case TAG_UNSIGNED_INT: \ + return (unsigned int)(value >> TAG_BITS); \ + case TAG_UNSIGNED_LONG: \ + return (unsigned long)(value >> TAG_BITS); \ + case TAG_UNSIGNED_LONG_LONG: \ + return (unsigned long long)(value >> TAG_BITS); \ + default: \ + @throw [OFInvalidArgumentException exception]; \ + } +- (long long)longLongValue +{ + RETURN_VALUE +} + +- (unsigned long long)unsignedLongLongValue +{ + RETURN_VALUE +} + +- (double)doubleValue +{ + RETURN_VALUE +} +@end +# undef RETURN_VALUE +#endif @implementation OFNumber -@synthesize type = _type; - -+ (instancetype)numberWithBool: (bool)bool_ -{ - return [[[self alloc] initWithBool: bool_] autorelease]; -} - -+ (instancetype)numberWithChar: (signed char)sChar -{ - return [[[self alloc] initWithChar: sChar] autorelease]; -} - -+ (instancetype)numberWithShort: (signed short)sShort -{ - return [[[self alloc] initWithShort: sShort] autorelease]; -} - -+ (instancetype)numberWithInt: (signed int)sInt -{ - return [[[self alloc] initWithInt: sInt] autorelease]; -} - -+ (instancetype)numberWithLong: (signed long)sLong -{ - return [[[self alloc] initWithLong: sLong] autorelease]; -} - -+ (instancetype)numberWithLongLong: (signed long long)sLongLong -{ - return [[[self alloc] initWithLongLong: sLongLong] autorelease]; -} - -+ (instancetype)numberWithUnsignedChar: (unsigned char)uChar -{ - return [[[self alloc] initWithUnsignedChar: uChar] autorelease]; -} - -+ (instancetype)numberWithUnsignedShort: (unsigned short)uShort -{ - return [[[self alloc] initWithUnsignedShort: uShort] autorelease]; -} - -+ (instancetype)numberWithUnsignedInt: (unsigned int)uInt -{ - return [[[self alloc] initWithUnsignedInt: uInt] autorelease]; -} - -+ (instancetype)numberWithUnsignedLong: (unsigned long)uLong -{ - return [[[self alloc] initWithUnsignedLong: uLong] autorelease]; -} - -+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)uLongLong -{ - return [[[self alloc] initWithUnsignedLongLong: uLongLong] autorelease]; -} - -+ (instancetype)numberWithInt8: (int8_t)int8 -{ - return [[[self alloc] initWithInt8: int8] autorelease]; -} - -+ (instancetype)numberWithInt16: (int16_t)int16 -{ - return [[[self alloc] initWithInt16: int16] autorelease]; -} - -+ (instancetype)numberWithInt32: (int32_t)int32 -{ - return [[[self alloc] initWithInt32: int32] autorelease]; -} - -+ (instancetype)numberWithInt64: (int64_t)int64 -{ - return [[[self alloc] initWithInt64: int64] autorelease]; -} - -+ (instancetype)numberWithUInt8: (uint8_t)uInt8 -{ - return [[[self alloc] initWithUInt8: uInt8] autorelease]; -} - -+ (instancetype)numberWithUInt16: (uint16_t)uInt16 -{ - return [[[self alloc] initWithUInt16: uInt16] autorelease]; -} - -+ (instancetype)numberWithUInt32: (uint32_t)uInt32 -{ - return [[[self alloc] initWithUInt32: uInt32] autorelease]; -} - -+ (instancetype)numberWithUInt64: (uint64_t)uInt64 -{ - return [[[self alloc] initWithUInt64: uInt64] autorelease]; -} - -+ (instancetype)numberWithSize: (size_t)size -{ - return [[[self alloc] initWithSize: size] autorelease]; -} - -+ (instancetype)numberWithSSize: (ssize_t)sSize -{ - return [[[self alloc] initWithSSize: sSize] autorelease]; -} - -+ (instancetype)numberWithIntMax: (intmax_t)intMax -{ - return [[[self alloc] initWithIntMax: intMax] autorelease]; -} - -+ (instancetype)numberWithUIntMax: (uintmax_t)uIntMax -{ - return [[[self alloc] initWithUIntMax: uIntMax] autorelease]; -} - -+ (instancetype)numberWithPtrDiff: (ptrdiff_t)ptrDiff -{ - return [[[self alloc] initWithPtrDiff: ptrDiff] autorelease]; -} - -+ (instancetype)numberWithIntPtr: (intptr_t)intPtr -{ - return [[[self alloc] initWithIntPtr: intPtr] autorelease]; -} - -+ (instancetype)numberWithUIntPtr: (uintptr_t)uIntPtr -{ - return [[[self alloc] initWithUIntPtr: uIntPtr] autorelease]; -} - -+ (instancetype)numberWithFloat: (float)float_ -{ - return [[[self alloc] initWithFloat: float_] autorelease]; -} - -+ (instancetype)numberWithDouble: (double)double_ -{ - return [[[self alloc] initWithDouble: double_] autorelease]; ++ (void)initialize +{ + if (self != [OFNumber class]) + return; + + placeholder.isa = [OFNumberPlaceholder class]; + +#ifdef OF_OBJFW_RUNTIME + numberTag = + objc_registerTaggedPointerClass([OFTaggedPointerNumber class]); +#endif +} + ++ (instancetype)of_alloc +{ + return [super alloc]; +} + ++ (instancetype)alloc +{ + if (self == [OFNumber class]) + return (id)&placeholder; + + return [super alloc]; +} + ++ (instancetype)numberWithBool: (bool)value +{ + return [[[self alloc] initWithBool: value] autorelease]; +} + ++ (instancetype)numberWithChar: (signed char)value +{ + return [[[self alloc] initWithChar: value] autorelease]; +} + ++ (instancetype)numberWithShort: (short)value +{ + return [[[self alloc] initWithShort: value] autorelease]; +} + ++ (instancetype)numberWithInt: (int)value +{ + return [[[self alloc] initWithInt: value] autorelease]; +} + ++ (instancetype)numberWithLong: (long)value +{ + return [[[self alloc] initWithLong: value] autorelease]; +} + ++ (instancetype)numberWithLongLong: (long long)value +{ + return [[[self alloc] initWithLongLong: value] autorelease]; +} + ++ (instancetype)numberWithUnsignedChar: (unsigned char)value +{ + return [[[self alloc] initWithUnsignedChar: value] autorelease]; +} + ++ (instancetype)numberWithUnsignedShort: (unsigned short)value +{ + return [[[self alloc] initWithUnsignedShort: value] autorelease]; +} + ++ (instancetype)numberWithUnsignedInt: (unsigned int)value +{ + return [[[self alloc] initWithUnsignedInt: value] autorelease]; +} + ++ (instancetype)numberWithUnsignedLong: (unsigned long)value +{ + return [[[self alloc] initWithUnsignedLong: value] autorelease]; +} + ++ (instancetype)numberWithUnsignedLongLong: (unsigned long long)value +{ + return [[[self alloc] initWithUnsignedLongLong: value] autorelease]; +} + ++ (instancetype)numberWithFloat: (float)value +{ + return [[[self alloc] initWithFloat: value] autorelease]; +} + ++ (instancetype)numberWithDouble: (double)value +{ + return [[[self alloc] initWithDouble: value] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } -- (instancetype)initWithBool: (bool)bool_ -{ - self = [super init]; - - _value.bool_ = bool_; - _type = OF_NUMBER_TYPE_BOOL; - - return self; -} - -- (instancetype)initWithChar: (signed char)sChar -{ - self = [super init]; - - _value.sChar = sChar; - _type = OF_NUMBER_TYPE_CHAR; - - return self; -} - -- (instancetype)initWithShort: (signed short)sShort -{ - self = [super init]; - - _value.sShort = sShort; - _type = OF_NUMBER_TYPE_SHORT; - - return self; -} - -- (instancetype)initWithInt: (signed int)sInt -{ - self = [super init]; - - _value.sInt = sInt; - _type = OF_NUMBER_TYPE_INT; - - return self; -} - -- (instancetype)initWithLong: (signed long)sLong -{ - self = [super init]; - - _value.sLong = sLong; - _type = OF_NUMBER_TYPE_LONG; - - return self; -} - -- (instancetype)initWithLongLong: (signed long long)sLongLong -{ - self = [super init]; - - _value.sLongLong = sLongLong; - _type = OF_NUMBER_TYPE_LONGLONG; - - return self; -} - -- (instancetype)initWithUnsignedChar: (unsigned char)uChar -{ - self = [super init]; - - _value.uChar = uChar; - _type = OF_NUMBER_TYPE_UCHAR; - - return self; -} - -- (instancetype)initWithUnsignedShort: (unsigned short)uShort -{ - self = [super init]; - - _value.uShort = uShort; - _type = OF_NUMBER_TYPE_USHORT; - - return self; -} - -- (instancetype)initWithUnsignedInt: (unsigned int)uInt -{ - self = [super init]; - - _value.uInt = uInt; - _type = OF_NUMBER_TYPE_UINT; - - return self; -} - -- (instancetype)initWithUnsignedLong: (unsigned long)uLong -{ - self = [super init]; - - _value.uLong = uLong; - _type = OF_NUMBER_TYPE_ULONG; - - return self; -} - -- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong -{ - self = [super init]; - - _value.uLongLong = uLongLong; - _type = OF_NUMBER_TYPE_ULONGLONG; - - return self; -} - -- (instancetype)initWithInt8: (int8_t)int8 -{ - self = [super init]; - - _value.int8 = int8; - _type = OF_NUMBER_TYPE_INT8; - - return self; -} - -- (instancetype)initWithInt16: (int16_t)int16 -{ - self = [super init]; - - _value.int16 = int16; - _type = OF_NUMBER_TYPE_INT16; - - return self; -} - -- (instancetype)initWithInt32: (int32_t)int32 -{ - self = [super init]; - - _value.int32 = int32; - _type = OF_NUMBER_TYPE_INT32; - - return self; -} - -- (instancetype)initWithInt64: (int64_t)int64 -{ - self = [super init]; - - _value.int64 = int64; - _type = OF_NUMBER_TYPE_INT64; - - return self; -} - -- (instancetype)initWithUInt8: (uint8_t)uInt8 -{ - self = [super init]; - - _value.uInt8 = uInt8; - _type = OF_NUMBER_TYPE_UINT8; - - return self; -} - -- (instancetype)initWithUInt16: (uint16_t)uInt16 -{ - self = [super init]; - - _value.uInt16 = uInt16; - _type = OF_NUMBER_TYPE_UINT16; - - return self; -} - -- (instancetype)initWithUInt32: (uint32_t)uInt32 -{ - self = [super init]; - - _value.uInt32 = uInt32; - _type = OF_NUMBER_TYPE_UINT32; - - return self; -} - -- (instancetype)initWithUInt64: (uint64_t)uInt64 -{ - self = [super init]; - - _value.uInt64 = uInt64; - _type = OF_NUMBER_TYPE_UINT64; - - return self; -} - -- (instancetype)initWithSize: (size_t)size -{ - self = [super init]; - - _value.size = size; - _type = OF_NUMBER_TYPE_SIZE; - - return self; -} - -- (instancetype)initWithSSize: (ssize_t)sSize -{ - self = [super init]; - - _value.sSize = sSize; - _type = OF_NUMBER_TYPE_SSIZE; - - return self; -} - -- (instancetype)initWithIntMax: (intmax_t)intMax -{ - self = [super init]; - - _value.intMax = intMax; - _type = OF_NUMBER_TYPE_INTMAX; - - return self; -} - -- (instancetype)initWithUIntMax: (uintmax_t)uIntMax -{ - self = [super init]; - - _value.uIntMax = uIntMax; - _type = OF_NUMBER_TYPE_UINTMAX; - - return self; -} - -- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff -{ - self = [super init]; - - _value.ptrDiff = ptrDiff; - _type = OF_NUMBER_TYPE_PTRDIFF; - - return self; -} - -- (instancetype)initWithIntPtr: (intptr_t)intPtr -{ - self = [super init]; - - _value.intPtr = intPtr; - _type = OF_NUMBER_TYPE_INTPTR; - - return self; -} - -- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr -{ - self = [super init]; - - _value.uIntPtr = uIntPtr; - _type = OF_NUMBER_TYPE_UINTPTR; - - return self; -} - -- (instancetype)initWithFloat: (float)float_ -{ - self = [super init]; - - _value.float_ = float_; - _type = OF_NUMBER_TYPE_FLOAT; - - return self; -} - -- (instancetype)initWithDouble: (double)double_ -{ - self = [super init]; - - _value.double_ = double_; - _type = OF_NUMBER_TYPE_DOUBLE; +- (instancetype)initWithBool: (bool)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(bool); + + return self; +} + +- (instancetype)initWithChar: (signed char)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(signed char); + + return self; +} + +- (instancetype)initWithShort: (short)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(short); + + return self; +} + +- (instancetype)initWithInt: (int)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(int); + + return self; +} + +- (instancetype)initWithLong: (long)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(long); + + return self; +} + +- (instancetype)initWithLongLong: (long long)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(long long); + + return self; +} + +- (instancetype)initWithUnsignedChar: (unsigned char)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(unsigned long); + + return self; +} + +- (instancetype)initWithUnsignedShort: (unsigned short)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(unsigned short); + + return self; +} + +- (instancetype)initWithUnsignedInt: (unsigned int)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(unsigned int); + + return self; +} + +- (instancetype)initWithUnsignedLong: (unsigned long)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(unsigned long); + + return self; +} + +- (instancetype)initWithUnsignedLongLong: (unsigned long long)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(unsigned long long); + + return self; +} + +- (instancetype)initWithPtrDiff: (ptrdiff_t)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(ptrdiff_t); + + return self; +} + +- (instancetype)initWithIntPtr: (intptr_t)value +{ + self = [super init]; + + _value.signed_ = value; + _typeEncoding = @encode(intptr_t); + + return self; +} + +- (instancetype)initWithUIntPtr: (uintptr_t)value +{ + self = [super init]; + + _value.unsigned_ = value; + _typeEncoding = @encode(uintptr_t); + + return self; +} + +- (instancetype)initWithFloat: (float)value +{ + self = [super init]; + + _value.float_ = value; + _typeEncoding = @encode(float); + + return self; +} + +- (instancetype)initWithDouble: (double)value +{ + self = [super init]; + + _value.float_ = value; + _typeEncoding = @encode(double); return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element @@ -530,46 +749,39 @@ @try { void *pool = objc_autoreleasePoolPush(); OFString *typeString; - if (![element.name isEqual: self.className] || + if (![element.name isEqual: @"OFNumber"] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; typeString = [element attributeForName: @"type"].stringValue; - if ([typeString isEqual: @"boolean"]) { - _type = OF_NUMBER_TYPE_BOOL; - - if ([[element stringValue] isEqual: @"true"]) - _value.bool_ = true; - else if ([[element stringValue] isEqual: @"false"]) - _value.bool_ = false; + if ([typeString isEqual: @"bool"]) { + OFString *stringValue = element.stringValue; + if ([stringValue isEqual: @"true"]) + self = [self initWithBool: true]; + else if ([stringValue isEqual: @"false"]) + self = [self initWithBool: false]; else @throw [OFInvalidArgumentException exception]; - } else if ([typeString isEqual: @"unsigned"]) { - /* - * FIXME: This will fail if the value is bigger than - * INTMAX_MAX! - */ - _type = OF_NUMBER_TYPE_UINTMAX; - _value.uIntMax = element.decimalValue; - } else if ([typeString isEqual: @"signed"]) { - _type = OF_NUMBER_TYPE_INTMAX; - _value.intMax = element.decimalValue; } else if ([typeString isEqual: @"float"]) { - _type = OF_NUMBER_TYPE_FLOAT; - _value.float_ = OF_BSWAP_FLOAT_IF_LE( - OF_INT_TO_FLOAT_RAW(OF_BSWAP32_IF_LE( - (uint32_t)element.hexadecimalValue))); - } else if ([typeString isEqual: @"double"]) { - _type = OF_NUMBER_TYPE_DOUBLE; - _value.double_ = OF_BSWAP_DOUBLE_IF_LE( - OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE( - (uint64_t)element.hexadecimalValue))); - } else + unsigned long long value = + [element unsignedLongLongValueWithBase: 16]; + + if (value > UINT64_MAX) + @throw [OFOutOfRangeException exception]; + + self = [self initWithDouble: OF_BSWAP_DOUBLE_IF_LE( + OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(value)))]; + } else if ([typeString isEqual: @"signed"]) + self = [self initWithLongLong: element.longLongValue]; + else if ([typeString isEqual: @"unsigned"]) + self = [self initWithUnsignedLongLong: + element.unsignedLongLongValue]; + else @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @@ -579,387 +791,130 @@ return self; } - (const char *)objCType { - switch (_type) { - case OF_NUMBER_TYPE_BOOL: - return @encode(bool); - case OF_NUMBER_TYPE_CHAR: - return @encode(signed char); - case OF_NUMBER_TYPE_SHORT: - return @encode(signed short); - case OF_NUMBER_TYPE_INT: - return @encode(signed int); - case OF_NUMBER_TYPE_LONG: - return @encode(signed long); - case OF_NUMBER_TYPE_LONGLONG: - return @encode(signed long long); - case OF_NUMBER_TYPE_UCHAR: - return @encode(unsigned char); - case OF_NUMBER_TYPE_USHORT: - return @encode(unsigned short); - case OF_NUMBER_TYPE_UINT: - return @encode(unsigned int); - case OF_NUMBER_TYPE_ULONG: - return @encode(unsigned long); - case OF_NUMBER_TYPE_ULONGLONG: - return @encode(unsigned long long); - case OF_NUMBER_TYPE_INT8: - return @encode(int8_t); - case OF_NUMBER_TYPE_INT16: - return @encode(int16_t); - case OF_NUMBER_TYPE_INT32: - return @encode(int32_t); - case OF_NUMBER_TYPE_INT64: - return @encode(int64_t); - case OF_NUMBER_TYPE_UINT8: - return @encode(uint8_t); - case OF_NUMBER_TYPE_UINT16: - return @encode(uint16_t); - case OF_NUMBER_TYPE_UINT32: - return @encode(uint32_t); - case OF_NUMBER_TYPE_UINT64: - return @encode(uint64_t); - case OF_NUMBER_TYPE_SIZE: - return @encode(size_t); - case OF_NUMBER_TYPE_SSIZE: - return @encode(ssize_t); - case OF_NUMBER_TYPE_INTMAX: - return @encode(intmax_t); - case OF_NUMBER_TYPE_UINTMAX: - return @encode(uintmax_t); - case OF_NUMBER_TYPE_PTRDIFF: - return @encode(ptrdiff_t); - case OF_NUMBER_TYPE_INTPTR: - return @encode(intptr_t); - case OF_NUMBER_TYPE_UINTPTR: - return @encode(uintptr_t); - case OF_NUMBER_TYPE_FLOAT: - return @encode(float); - case OF_NUMBER_TYPE_DOUBLE: - return @encode(double); - default: - @throw [OFInvalidFormatException exception]; - } -} - -- (void)getValue: (void *)value - size: (size_t)size -{ - switch (_type) { - case OF_NUMBER_TYPE_BOOL: - if (size != sizeof(bool)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.bool_, sizeof(bool)); - break; - case OF_NUMBER_TYPE_CHAR: - if (size != sizeof(signed char)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.sChar, sizeof(signed char)); - break; - case OF_NUMBER_TYPE_SHORT: - if (size != sizeof(signed short)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.sShort, sizeof(signed short)); - break; - case OF_NUMBER_TYPE_INT: - if (size != sizeof(signed int)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.sInt, sizeof(signed int)); - break; - case OF_NUMBER_TYPE_LONG: - if (size != sizeof(signed long)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.sLong, sizeof(signed long)); - break; - case OF_NUMBER_TYPE_LONGLONG: - if (size != sizeof(signed long long)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.sLongLong, sizeof(signed long long)); - break; - case OF_NUMBER_TYPE_UCHAR: - if (size != sizeof(unsigned char)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uChar, sizeof(unsigned char)); - break; - case OF_NUMBER_TYPE_USHORT: - if (size != sizeof(unsigned short)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uShort, sizeof(unsigned short)); - break; - case OF_NUMBER_TYPE_UINT: - if (size != sizeof(unsigned int)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uInt, sizeof(unsigned int)); - break; - case OF_NUMBER_TYPE_ULONG: - if (size != sizeof(unsigned long)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uLong, sizeof(unsigned long)); - break; - case OF_NUMBER_TYPE_ULONGLONG: - if (size != sizeof(unsigned long long)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uLongLong, sizeof(unsigned long long)); - break; - case OF_NUMBER_TYPE_INT8: - if (size != sizeof(int8_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.int8, sizeof(int8_t)); - break; - case OF_NUMBER_TYPE_INT16: - if (size != sizeof(int16_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.int16, sizeof(int16_t)); - break; - case OF_NUMBER_TYPE_INT32: - if (size != sizeof(int32_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.int32, sizeof(int32_t)); - break; - case OF_NUMBER_TYPE_INT64: - if (size != sizeof(int64_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.int64, sizeof(int64_t)); - break; - case OF_NUMBER_TYPE_UINT8: - if (size != sizeof(uint8_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uInt8, sizeof(uint8_t)); - break; - case OF_NUMBER_TYPE_UINT16: - if (size != sizeof(uint16_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uInt16, sizeof(uint16_t)); - break; - case OF_NUMBER_TYPE_UINT32: - if (size != sizeof(uint32_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uInt32, sizeof(uint32_t)); - break; - case OF_NUMBER_TYPE_UINT64: - if (size != sizeof(uint64_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uInt64, sizeof(uint64_t)); - break; - case OF_NUMBER_TYPE_SIZE: - if (size != sizeof(size_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.size, sizeof(size_t)); - break; - case OF_NUMBER_TYPE_SSIZE: - if (size != sizeof(ssize_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.sSize, sizeof(ssize_t)); - break; - case OF_NUMBER_TYPE_INTMAX: - if (size != sizeof(intmax_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.intMax, sizeof(intmax_t)); - break; - case OF_NUMBER_TYPE_UINTMAX: - if (size != sizeof(uintmax_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uIntMax, sizeof(uintmax_t)); - break; - case OF_NUMBER_TYPE_PTRDIFF: - if (size != sizeof(ptrdiff_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.ptrDiff, sizeof(ptrdiff_t)); - break; - case OF_NUMBER_TYPE_INTPTR: - if (size != sizeof(intptr_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.intPtr, sizeof(intptr_t)); - break; - case OF_NUMBER_TYPE_UINTPTR: - if (size != sizeof(uintptr_t)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.uIntPtr, sizeof(uintptr_t)); - break; - case OF_NUMBER_TYPE_FLOAT: - if (size != sizeof(float)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.float_, sizeof(float)); - break; - case OF_NUMBER_TYPE_DOUBLE: - if (size != sizeof(double)) - @throw [OFOutOfRangeException exception]; - - memcpy(value, &_value.double_, sizeof(double)); - break; - default: - @throw [OFInvalidFormatException exception]; - } -} - -- (bool)boolValue -{ - RETURN_AS(bool) -} - -- (signed char)charValue -{ - RETURN_AS(signed char) -} - -- (signed short)shortValue -{ - RETURN_AS(signed short) -} - -- (signed int)intValue -{ - RETURN_AS(signed int) -} - -- (signed long)longValue -{ - RETURN_AS(signed long) -} - -- (signed long long)longLongValue -{ - RETURN_AS(signed long long) -} - -- (unsigned char)unsignedCharValue -{ - RETURN_AS(unsigned char) -} - -- (unsigned short)unsignedShortValue -{ - RETURN_AS(unsigned short) -} - -- (unsigned int)unsignedIntValue -{ - RETURN_AS(unsigned int) -} - -- (unsigned long)unsignedLongValue -{ - RETURN_AS(unsigned long) -} - -- (unsigned long long)unsignedLongLongValue -{ - RETURN_AS(unsigned long long) -} - -- (int8_t)int8Value -{ - RETURN_AS(int8_t) -} - -- (int16_t)int16Value -{ - RETURN_AS(int16_t) -} - -- (int32_t)int32Value -{ - RETURN_AS(int32_t) -} - -- (int64_t)int64Value -{ - RETURN_AS(int64_t) -} - -- (uint8_t)uInt8Value -{ - RETURN_AS(uint8_t) -} - -- (uint16_t)uInt16Value -{ - RETURN_AS(uint16_t) -} - -- (uint32_t)uInt32Value -{ - RETURN_AS(uint32_t) -} - -- (uint64_t)uInt64Value -{ - RETURN_AS(uint64_t) -} - -- (size_t)sizeValue -{ - RETURN_AS(size_t) -} - -- (ssize_t)sSizeValue -{ - RETURN_AS(ssize_t) -} - -- (intmax_t)intMaxValue -{ - RETURN_AS(intmax_t) -} - -- (uintmax_t)uIntMaxValue -{ - RETURN_AS(uintmax_t) -} - -- (ptrdiff_t)ptrDiffValue -{ - RETURN_AS(ptrdiff_t) -} - -- (intptr_t)intPtrValue -{ - RETURN_AS(intptr_t) -} - -- (uintptr_t)uIntPtrValue -{ - RETURN_AS(uintptr_t) -} - -- (float)floatValue -{ - RETURN_AS(float) -} - -- (double)doubleValue -{ - RETURN_AS(double) + return _typeEncoding; +} + +- (void)getValue: (void *)value + size: (size_t)size +{ + switch (*self.objCType) { +#define CASE(enc, type, property) \ + case enc: { \ + type tmp = (type)self.property; \ + \ + if (size != sizeof(type)) \ + @throw [OFOutOfRangeException exception]; \ + \ + memcpy(value, &tmp, size); \ + break; \ + } + CASE('B', bool, unsignedLongLongValue) + CASE('c', signed char, longLongValue) + CASE('s', short, longLongValue) + CASE('i', int, longLongValue) + CASE('l', long, longLongValue) + CASE('q', long long, longLongValue) + CASE('C', unsigned char, unsignedLongLongValue) + CASE('S', unsigned short, unsignedLongLongValue) + CASE('I', unsigned int, unsignedLongLongValue) + CASE('L', unsigned long, unsignedLongLongValue) + CASE('Q', unsigned long long, unsignedLongLongValue) + CASE('f', float, doubleValue) + CASE('d', double, doubleValue) +#undef CASE + default: + @throw [OFInvalidFormatException exception]; + } +} + +- (long long)longLongValue +{ + if (isFloat(self)) + return _value.float_; + else if (isSigned(self)) + return _value.signed_; + else if (isUnsigned(self)) + return _value.unsigned_; + else + @throw [OFInvalidFormatException exception]; +} + +- (unsigned long long)unsignedLongLongValue +{ + if (isFloat(self)) + return _value.float_; + else if (isSigned(self)) + return _value.signed_; + else if (isUnsigned(self)) + return _value.unsigned_; + else + @throw [OFInvalidFormatException exception]; +} + +- (double)doubleValue +{ + if (isFloat(self)) + return _value.float_; + else if (isSigned(self)) + return _value.signed_; + else if (isUnsigned(self)) + return _value.unsigned_; + else + @throw [OFInvalidFormatException exception]; +} + +- (bool)boolValue +{ + return (bool)self.unsignedLongLongValue; +} + +- (signed char)charValue +{ + return (signed char)self.longLongValue; +} + +- (short)shortValue +{ + return (short)self.longLongValue; +} + +- (int)intValue +{ + return (int)self.longLongValue; +} + +- (long)longValue +{ + return (long)self.longLongValue; +} + +- (unsigned char)unsignedCharValue +{ + return (unsigned char)self.unsignedLongLongValue; +} + +- (unsigned short)unsignedShortValue +{ + return (unsigned short)self.unsignedLongLongValue; +} + +- (unsigned int)unsignedIntValue +{ + return (unsigned int)self.unsignedLongLongValue; +} + +- (unsigned long)unsignedLongValue +{ + return (unsigned long)self.unsignedLongLongValue; +} + +- (float)floatValue +{ + return (float)self.doubleValue; } - (bool)isEqual: (id)object { OFNumber *number; @@ -970,12 +925,11 @@ if (![object isKindOfClass: [OFNumber class]]) return false; number = object; - if (_type & OF_NUMBER_TYPE_FLOAT || - number->_type & OF_NUMBER_TYPE_FLOAT) { + if (isFloat(self) || isFloat(number)) { double value1 = number.doubleValue; double value2 = self.doubleValue; if (isnan(value1) && isnan(value2)) return true; @@ -983,15 +937,14 @@ return false; return (value1 == value2); } - if (_type & OF_NUMBER_TYPE_SIGNED || - number->_type & OF_NUMBER_TYPE_SIGNED) - return (number.intMaxValue == self.intMaxValue); + if (isSigned(self) || isSigned(number)) + return (number.longLongValue == self.longLongValue); - return (number.uIntMaxValue == self.uIntMaxValue); + return (number.unsignedLongLongValue == self.unsignedLongLongValue); } - (of_comparison_result_t)compare: (id )object { OFNumber *number; @@ -999,35 +952,33 @@ if (![(id)object isKindOfClass: [OFNumber class]]) @throw [OFInvalidArgumentException exception]; number = (OFNumber *)object; - if (_type & OF_NUMBER_TYPE_FLOAT || - number->_type & OF_NUMBER_TYPE_FLOAT) { + if (isFloat(self) || isFloat(number)) { double double1 = self.doubleValue; double double2 = number.doubleValue; if (double1 > double2) return OF_ORDERED_DESCENDING; if (double1 < double2) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; - } else if (_type & OF_NUMBER_TYPE_SIGNED || - number->_type & OF_NUMBER_TYPE_SIGNED) { - intmax_t int1 = self.intMaxValue; - intmax_t int2 = number.intMaxValue; + } else if (isSigned(self) || isSigned(number)) { + long long int1 = self.longLongValue; + long long int2 = number.longLongValue; if (int1 > int2) return OF_ORDERED_DESCENDING; if (int1 < int2) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } else { - uintmax_t uint1 = self.uIntMaxValue; - uintmax_t uint2 = number.uIntMaxValue; + unsigned long long uint1 = self.unsignedLongLongValue; + unsigned long long uint2 = number.unsignedLongLongValue; if (uint1 > uint2) return OF_ORDERED_DESCENDING; if (uint1 < uint2) return OF_ORDERED_ASCENDING; @@ -1036,61 +987,33 @@ } } - (uint32_t)hash { - of_number_type_t type = _type; uint32_t hash; - /* Do we really need signed to represent this number? */ - if (type & OF_NUMBER_TYPE_SIGNED && self.intMaxValue >= 0) - type &= ~OF_NUMBER_TYPE_SIGNED; - - /* Do we really need floating point to represent this number? */ - if (type & OF_NUMBER_TYPE_FLOAT) { - double v = self.doubleValue; - - if (v < 0) { - if (v == self.intMaxValue) { - type &= ~OF_NUMBER_TYPE_FLOAT; - type |= OF_NUMBER_TYPE_SIGNED; - } - } else { - if (v == self.uIntMaxValue) - type &= ~OF_NUMBER_TYPE_FLOAT; - } - } - OF_HASH_INIT(hash); - if (type & OF_NUMBER_TYPE_FLOAT) { + if (isFloat(self)) { double d; if (isnan(self.doubleValue)) return 0; d = OF_BSWAP_DOUBLE_IF_BE(self.doubleValue); for (uint_fast8_t i = 0; i < sizeof(double); i++) OF_HASH_ADD(hash, ((char *)&d)[i]); - } else if (type & OF_NUMBER_TYPE_SIGNED) { - intmax_t v = self.intMaxValue * -1; - - while (v != 0) { - OF_HASH_ADD(hash, v & 0xFF); - v >>= 8; - } - - OF_HASH_ADD(hash, 1); - } else { - uintmax_t v = self.uIntMaxValue; - - while (v != 0) { - OF_HASH_ADD(hash, v & 0xFF); - v >>= 8; - } - } + } else if (isSigned(self) || isUnsigned(self)) { + unsigned long long value = self.unsignedLongLongValue; + + while (value != 0) { + OF_HASH_ADD(hash, value & 0xFF); + value >>= 8; + } + } else + @throw [OFInvalidFormatException exception]; OF_HASH_FINALIZE(hash); return hash; } @@ -1105,130 +1028,50 @@ return [self stringValue]; } - (OFString *)stringValue { - OFMutableString *ret; - - switch (_type) { - case OF_NUMBER_TYPE_BOOL: - return (_value.bool_ ? @"true" : @"false"); - case OF_NUMBER_TYPE_UCHAR: - case OF_NUMBER_TYPE_USHORT: - case OF_NUMBER_TYPE_UINT: - case OF_NUMBER_TYPE_ULONG: - case OF_NUMBER_TYPE_ULONGLONG: - case OF_NUMBER_TYPE_UINT8: - case OF_NUMBER_TYPE_UINT16: - case OF_NUMBER_TYPE_UINT32: - case OF_NUMBER_TYPE_UINT64: - case OF_NUMBER_TYPE_SIZE: - case OF_NUMBER_TYPE_UINTMAX: - case OF_NUMBER_TYPE_UINTPTR: - return [OFString stringWithFormat: @"%ju", self.uIntMaxValue]; - case OF_NUMBER_TYPE_CHAR: - case OF_NUMBER_TYPE_SHORT: - case OF_NUMBER_TYPE_INT: - case OF_NUMBER_TYPE_LONG: - case OF_NUMBER_TYPE_LONGLONG: - case OF_NUMBER_TYPE_INT8: - case OF_NUMBER_TYPE_INT16: - case OF_NUMBER_TYPE_INT32: - case OF_NUMBER_TYPE_INT64: - case OF_NUMBER_TYPE_SSIZE: - case OF_NUMBER_TYPE_INTMAX: - case OF_NUMBER_TYPE_PTRDIFF: - case OF_NUMBER_TYPE_INTPTR: - return [OFString stringWithFormat: @"%jd", self.intMaxValue]; - case OF_NUMBER_TYPE_FLOAT: - ret = [OFMutableString stringWithFormat: @"%g", _value.float_]; - - if (![ret containsString: @"."]) - [ret appendString: @".0"]; - - [ret makeImmutable]; - - return ret; - case OF_NUMBER_TYPE_DOUBLE: - ret = [OFMutableString stringWithFormat: @"%g", _value.double_]; - - if (![ret containsString: @"."]) - [ret appendString: @".0"]; - - [ret makeImmutable]; - - return ret; - default: - @throw [OFInvalidFormatException exception]; - } + if (*self.objCType == 'B') + return (self.boolValue ? @"true" : @"false"); + if (isFloat(self)) + return [OFString stringWithFormat: @"%g", self.doubleValue]; + if (isSigned(self)) + return [OFString stringWithFormat: @"%lld", self.longLongValue]; + if (isUnsigned(self)) + return [OFString stringWithFormat: @"%llu", + self.unsignedLongLongValue]; + + @throw [OFInvalidFormatException exception]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; - element = [OFXMLElement elementWithName: self.className + element = [OFXMLElement elementWithName: @"OFNumber" namespace: OF_SERIALIZATION_NS stringValue: self.description]; - switch (_type) { - case OF_NUMBER_TYPE_BOOL: - [element addAttributeWithName: @"type" - stringValue: @"boolean"]; - break; - case OF_NUMBER_TYPE_UCHAR: - case OF_NUMBER_TYPE_USHORT: - case OF_NUMBER_TYPE_UINT: - case OF_NUMBER_TYPE_ULONG: - case OF_NUMBER_TYPE_ULONGLONG: - case OF_NUMBER_TYPE_UINT8: - case OF_NUMBER_TYPE_UINT16: - case OF_NUMBER_TYPE_UINT32: - case OF_NUMBER_TYPE_UINT64: - case OF_NUMBER_TYPE_SIZE: - case OF_NUMBER_TYPE_UINTMAX: - case OF_NUMBER_TYPE_UINTPTR: - [element addAttributeWithName: @"type" - stringValue: @"unsigned"]; - break; - case OF_NUMBER_TYPE_CHAR: - case OF_NUMBER_TYPE_SHORT: - case OF_NUMBER_TYPE_INT: - case OF_NUMBER_TYPE_LONG: - case OF_NUMBER_TYPE_LONGLONG: - case OF_NUMBER_TYPE_INT8: - case OF_NUMBER_TYPE_INT16: - case OF_NUMBER_TYPE_INT32: - case OF_NUMBER_TYPE_INT64: - case OF_NUMBER_TYPE_SSIZE: - case OF_NUMBER_TYPE_INTMAX: - case OF_NUMBER_TYPE_PTRDIFF: - case OF_NUMBER_TYPE_INTPTR: - [element addAttributeWithName: @"type" - stringValue: @"signed"]; - break; - case OF_NUMBER_TYPE_FLOAT: + if (*self.objCType == 'B') + [element addAttributeWithName: @"type" + stringValue: @"bool"]; + else if (isFloat(self)) { [element addAttributeWithName: @"type" stringValue: @"float"]; - element.stringValue = [OFString stringWithFormat: @"%08" PRIx32, - OF_BSWAP32_IF_LE(OF_FLOAT_TO_INT_RAW(OF_BSWAP_FLOAT_IF_LE( - _value.float_)))]; - - break; - case OF_NUMBER_TYPE_DOUBLE: - [element addAttributeWithName: @"type" - stringValue: @"double"]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OF_BSWAP64_IF_LE(OF_DOUBLE_TO_INT_RAW(OF_BSWAP_DOUBLE_IF_LE( - _value.double_)))]; - - break; - default: + self.doubleValue)))]; + } else if (isSigned(self)) + [element addAttributeWithName: @"type" + stringValue: @"signed"]; + else if (isUnsigned(self)) + [element addAttributeWithName: @"type" + stringValue: @"unsigned"]; + else @throw [OFInvalidFormatException exception]; - } [element retain]; objc_autoreleasePoolPop(pool); @@ -1250,12 +1093,12 @@ - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth { double doubleValue; - if (_type == OF_NUMBER_TYPE_BOOL) - return (_value.bool_ ? @"true" : @"false"); + if (*self.objCType == 'B') + return (self.boolValue ? @"true" : @"false"); doubleValue = self.doubleValue; if (isinf(doubleValue)) { if (options & OF_JSON_REPRESENTATION_JSON5) { if (doubleValue > 0) @@ -1270,38 +1113,39 @@ } - (OFData *)messagePackRepresentation { OFMutableData *data; + const char *typeEncoding = self.objCType; - if (_type == OF_NUMBER_TYPE_BOOL) { - uint8_t type = (_value.bool_ ? 0xC3 : 0xC2); + if (*typeEncoding == 'B') { + uint8_t type = (self.boolValue ? 0xC3 : 0xC2); data = [OFMutableData dataWithItems: &type count: 1]; - } else if (_type == OF_NUMBER_TYPE_FLOAT) { + } else if (*typeEncoding == 'f') { uint8_t type = 0xCA; - float tmp = OF_BSWAP_FLOAT_IF_LE(_value.float_); + float tmp = OF_BSWAP_FLOAT_IF_LE(self.floatValue); data = [OFMutableData dataWithItemSize: 1 capacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; - } else if (_type == OF_NUMBER_TYPE_DOUBLE) { + } else if (*typeEncoding == 'd') { uint8_t type = 0xCB; - double tmp = OF_BSWAP_DOUBLE_IF_LE(_value.double_); + double tmp = OF_BSWAP_DOUBLE_IF_LE(self.doubleValue); data = [OFMutableData dataWithItemSize: 1 capacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; - } else if (_type & OF_NUMBER_TYPE_SIGNED) { - intmax_t value = self.intMaxValue; + } else if (isSigned(self)) { + long long value = self.longLongValue; if (value >= -32 && value < 0) { uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F); data = [OFMutableData dataWithItems: &tmp @@ -1345,12 +1189,12 @@ [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; - } else { - uintmax_t value = self.uIntMaxValue; + } else if (isUnsigned(self)) { + unsigned long long value = self.unsignedLongLongValue; if (value <= 127) { uint8_t tmp = ((uint8_t)value & 0x7F); data = [OFMutableData dataWithItems: &tmp @@ -1394,12 +1238,13 @@ [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; - } + } else + @throw [OFInvalidFormatException exception]; [data makeImmutable]; return data; } @end Index: src/OFObject+Serialization.h ================================================================== --- src/OFObject+Serialization.h +++ src/OFObject+Serialization.h @@ -28,12 +28,12 @@ #ifdef __cplusplus } #endif @interface OFObject (OFSerialization) -/*! +/** * @brief The object serialized as a string. */ @property (readonly, nonatomic) OFString *stringBySerializing; @end OF_ASSUME_NONNULL_END Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -30,12 +30,13 @@ #include #include #include #include -#include "macros.h" #include "block.h" +#include "macros.h" +#include "once.h" /* * Some versions of MinGW require to be included before * . Do this here to make sure this is always done in the correct * order, even if another header includes just . @@ -48,26 +49,26 @@ # endif #endif OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ -/*! +/** * @brief A result of a comparison. */ typedef enum { - /*! The left object is smaller than the right */ + /** The left object is smaller than the right */ OF_ORDERED_ASCENDING = -1, - /*! Both objects are equal */ + /** Both objects are equal */ OF_ORDERED_SAME = 0, - /*! The left object is bigger than the right */ + /** The left object is bigger than the right */ OF_ORDERED_DESCENDING = 1 } of_comparison_result_t; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A comparator to compare two objects. * * @param left The left object * @param right The right object * @return The order of the objects @@ -74,34 +75,34 @@ */ typedef of_comparison_result_t (^of_comparator_t)(id _Nonnull left, id _Nonnull right); #endif -/*! +/** * @brief An enum for storing endianess. */ typedef enum { - /*! Most significant byte first (big endian) */ + /** Most significant byte first (big endian) */ OF_BYTE_ORDER_BIG_ENDIAN, - /*! Least significant byte first (little endian) */ + /** Least significant byte first (little endian) */ OF_BYTE_ORDER_LITTLE_ENDIAN } of_byte_order_t; -/*! +/** * @struct of_range_t OFObject.h ObjFW/OFObject.h * * @brief A range. */ struct OF_BOXABLE of_range_t { - /*! The start of the range */ + /** The start of the range */ size_t location; - /*! The length of the range */ + /** The length of the range */ size_t length; }; typedef struct of_range_t of_range_t; -/*! +/** * @brief Creates a new of_range_t. * * @param start The starting index of the range * @param length The length of the range * @return An of_range with the specified start and length @@ -112,11 +113,11 @@ of_range_t range = { start, length }; return range; } -/*! +/** * @brief Returns whether the two ranges are equal. * * @param range1 The first range for the comparison * @param range2 The second range for the comparison * @return Whether the two ranges are equal @@ -131,29 +132,29 @@ return false; return true; } -/*! +/** * @brief A time interval in seconds. */ typedef double of_time_interval_t; -/*! +/** * @struct of_point_t OFObject.h ObjFW/OFObject.h * * @brief A point. */ struct OF_BOXABLE of_point_t { - /*! The x coordinate of the point */ + /** The x coordinate of the point */ float x; - /*! The y coordinate of the point */ + /** The y coordinate of the point */ float y; }; typedef struct of_point_t of_point_t; -/*! +/** * @brief Creates a new of_point_t. * * @param x The x coordinate of the point * @param y The x coordinate of the point * @return An of_point_t with the specified coordinates @@ -164,11 +165,11 @@ of_point_t point = { x, y }; return point; } -/*! +/** * @brief Returns whether the two points are equal. * * @param point1 The first point for the comparison * @param point2 The second point for the comparison * @return Whether the two points are equal @@ -183,24 +184,24 @@ return false; return true; } -/*! +/** * @struct of_dimension_t OFObject.h ObjFW/OFObject.h * * @brief A dimension. */ struct OF_BOXABLE of_dimension_t { - /*! The width of the dimension */ + /** The width of the dimension */ float width; - /*! The height of the dimension */ + /** The height of the dimension */ float height; }; typedef struct of_dimension_t of_dimension_t; -/*! +/** * @brief Creates a new of_dimension_t. * * @param width The width of the dimension * @param height The height of the dimension * @return An of_dimension_t with the specified width and height @@ -211,11 +212,11 @@ of_dimension_t dimension = { width, height }; return dimension; } -/*! +/** * @brief Returns whether the two dimensions are equal. * * @param dimension1 The first dimension for the comparison * @param dimension2 The second dimension for the comparison * @return Whether the two dimensions are equal @@ -230,24 +231,24 @@ return false; return true; } -/*! +/** * @struct of_rectangle_t OFObject.h ObjFW/OFObject.h * * @brief A rectangle. */ struct OF_BOXABLE of_rectangle_t { - /*! The point from where the rectangle originates */ + /** The point from where the rectangle originates */ of_point_t origin; - /*! The size of the rectangle */ + /** The size of the rectangle */ of_dimension_t size; }; typedef struct of_rectangle_t of_rectangle_t; -/*! +/** * @brief Creates a new of_rectangle_t. * * @param x The x coordinate of the top left corner of the rectangle * @param y The y coordinate of the top left corner of the rectangle * @param width The width of the rectangle @@ -263,11 +264,11 @@ }; return rectangle; } -/*! +/** * @brief Returns whether the two rectangles are equal. * * @param rectangle1 The first rectangle for the comparison * @param rectangle2 The second rectangle for the comparison * @return Whether the two rectangles are equal @@ -287,108 +288,116 @@ #ifdef __OBJC__ @class OFMethodSignature; @class OFString; @class OFThread; -/*! +/** * @protocol OFObject OFObject.h ObjFW/OFObject.h * * @brief The protocol which all root classes implement. */ @protocol OFObject -/*! - * @brief The class of the object. - */ -# ifndef __cplusplus -@property (readonly, nonatomic) Class class; -# else -@property (readonly, nonatomic, getter=class) Class class_; -# endif - -/*! - * @brief The superclass of the object. - */ -@property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass; - -/*! - * @brief A 32 bit hash for the object. +/** + * @brief Returns the class of the object. + * + * @return The class of the object + */ +- (Class)class; + +/** + * @brief Returns the superclass of the object. + * + * @return The superclass of the object + */ +- (nullable Class)superclass; + +/** + * @brief Returns a 32 bit hash for the object. * * Classes containing data (like strings, arrays, lists etc.) should reimplement * this! * * @warning If you reimplement this, you also need to reimplement @ref isEqual: * to behave in a way compatible to your reimplementation of this * method! - */ -@property (readonly, nonatomic) uint32_t hash; - -/*! - * @brief The retain count. - */ -@property (readonly, nonatomic) unsigned int retainCount; - -/*! - * @brief Whether the object is a proxy object. - */ -@property (readonly, nonatomic) bool isProxy; - -/*! - * @brief Whether the object allows weak references. - */ -@property (readonly, nonatomic) bool allowsWeakReference; - -/*! + * + * @return A 32 bit hash for the object + */ +- (uint32_t)hash; + +/** + * @brief Returns the retain count. + * + * @return The retain count + */ +- (unsigned int)retainCount; + +/** + * @brief Returns whether the object is a proxy object. + * + * @return Whether the object is a proxy object + */ +- (bool)isProxy; + +/** + * @brief Returns whether the object allows weak references. + * + * @return Whether the object allows weak references + */ +- (bool)allowsWeakReference; + +/** * @brief Returns a boolean whether the object of the specified kind. * * @param class_ The class whose kind is checked * @return A boolean whether the object is of the specified kind */ - (bool)isKindOfClass: (Class)class_; -/*! +/** * @brief Returns a boolean whether the object is a member of the specified * class. * * @param class_ The class for which the receiver is checked * @return A boolean whether the object is a member of the specified class */ - (bool)isMemberOfClass: (Class)class_; -/*! +/** * @brief Returns a boolean whether the object responds to the specified * selector. * * @param selector The selector which should be checked for respondence * @return A boolean whether the objects responds to the specified selector */ - (bool)respondsToSelector: (SEL)selector; -/*! +/** * @brief Checks whether the object conforms to the specified protocol. * * @param protocol The protocol which should be checked for conformance * @return A boolean whether the object conforms to the specified protocol */ - (bool)conformsToProtocol: (Protocol *)protocol; -/*! +/** * @brief Returns the implementation for the specified selector. * * @param selector The selector for which the method should be returned * @return The implementation for the specified selector */ - (nullable IMP)methodForSelector: (SEL)selector; -/*! +/** * @brief Performs the specified selector. * * @param selector The selector to perform * @return The object returned by the method specified by the selector */ - (nullable id)performSelector: (SEL)selector; -/*! +/** * @brief Performs the specified selector with the specified object. * * @param selector The selector to perform * @param object The object that is passed to the method specified by the * selector @@ -395,11 +404,11 @@ * @return The object returned by the method specified by the selector */ - (nullable id)performSelector: (SEL)selector withObject: (nullable id)object; -/*! +/** * @brief Performs the specified selector with the specified objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the * selector @@ -409,11 +418,11 @@ */ - (nullable id)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2; -/*! +/** * @brief Performs the specified selector with the specified objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the * selector @@ -426,11 +435,11 @@ - (nullable id)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3; -/*! +/** * @brief Performs the specified selector with the specified objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the * selector @@ -446,11 +455,11 @@ withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4; -/*! +/** * @brief Checks two objects for equality. * * Classes containing data (like strings, arrays, lists etc.) should reimplement * this! * @@ -460,51 +469,51 @@ * @param object The object which should be tested for equality * @return A boolean whether the object is equal to the specified object */ - (bool)isEqual: (nullable id)object; -/*! +/** * @brief Increases the retain count. * * Each time an object is released, the retain count gets decreased and the * object deallocated if it reaches 0. */ - (instancetype)retain; -/*! +/** * @brief Decreases the retain count. * * Each time an object is released, the retain count gets decreased and the * object deallocated if it reaches 0. */ - (void)release; -/*! +/** * @brief Adds the object to the topmost autorelease pool of the thread's * autorelease pool stack. * * @return The object */ - (instancetype)autorelease; -/*! +/** * @brief Returns the receiver. * * @return The receiver */ - (instancetype)self; -/*! +/** * @brief Retain a weak reference to this object. * * @return Whether a weak reference to this object has been retained */ - (bool)retainWeakReference; @end #endif -/*! +/** * @class OFObject OFObject.h ObjFW/OFObject.h * * @brief The root class for all other classes inside ObjFW. */ #ifdef __OBJC__ @@ -528,33 +537,44 @@ @property (class, readonly, nonatomic) OFString *className; @property (class, readonly, nullable, nonatomic) Class superclass; @property (class, readonly, nonatomic) OFString *description; # endif -/*! +# ifdef __cplusplus +@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 int retainCount; +@property (readonly, nonatomic) bool isProxy; +@property (readonly, nonatomic) bool allowsWeakReference; + +/** * @brief The name of the object's class. */ @property (readonly, nonatomic) OFString *className; -/*! +/** * @brief A description for the object. * * This is used when the object is used in a format string and for debugging * purposes. */ @property (readonly, nonatomic) OFString *description; -/*! +/** * @brief A method which is called once when the class is loaded into the * runtime. * * Derived classes can override this to execute their own code when the class * is loaded. */ + (void)load; -/*! +/** * @brief A method which is called when the class is unloaded from the runtime. * * Derived classes can override this to execute their own code when the class * is unloaded. * @@ -564,11 +584,11 @@ * In the future, this might also be called by the ObjFW runtime when * the class is part of a plugin that has been unloaded. */ + (void)unload; -/*! +/** * @brief A method which is called the moment before the first call to the class * is being made. * * Derived classes can override this to execute their own code on * initialization. They should make sure to not execute any code if self is not @@ -575,11 +595,11 @@ * the class itself, as it might happen that the method was called for a * subclass which did not override this method. */ + (void)initialize; -/*! +/** * @brief Allocates memory for an instance of the class and sets up the memory * pool for the object. * * This method will never return `nil`, instead, it will throw an * @ref OFAllocFailedException. @@ -586,75 +606,75 @@ * * @return The allocated object */ + (instancetype)alloc; -/*! +/** * @brief Calls @ref alloc on `self` and then `init` on the returned object. * * @return An allocated and initialized object */ + (instancetype)new; -/*! +/** * @brief Returns the class. * * @return The class */ + (Class)class; -/*! +/** * @brief Returns the name of the class as a string. * * @return The name of the class as a string */ + (OFString *)className; -/*! +/** * @brief Returns a boolean whether the class is a subclass of the specified * class. * * @param class_ The class which is checked for being a superclass * @return A boolean whether the class is a subclass of the specified class */ + (bool)isSubclassOfClass: (Class)class_; -/*! +/** * @brief Returns the superclass of the class. * * @return The superclass of the class */ + (nullable Class)superclass; -/*! +/** * @brief Checks whether instances of the class respond to a given selector. * * @param selector The selector which should be checked for respondence * @return A boolean whether instances of the class respond to the specified * selector */ + (bool)instancesRespondToSelector: (SEL)selector; -/*! +/** * @brief Checks whether the class conforms to a given protocol. * * @param protocol The protocol which should be checked for conformance * @return A boolean whether the class conforms to the specified protocol */ + (bool)conformsToProtocol: (Protocol *)protocol; -/*! +/** * @brief Returns the implementation of the instance method for the specified * selector. * * @param selector The selector for which the method should be returned * @return The implementation of the instance method for the specified selector * or `nil` if it isn't implemented */ + (nullable IMP)instanceMethodForSelector: (SEL)selector; -/*! +/** * @brief Returns the method signature of the instance method for the specified * selector. * * @param selector The selector for which the method signature should be * returned @@ -662,30 +682,30 @@ * selector */ + (nullable OFMethodSignature *) instanceMethodSignatureForSelector: (SEL)selector; -/*! +/** * @brief Returns a description for the class, which is usually the class name. * * This is mostly for debugging purposes. * * @return A description for the class, which is usually the class name */ + (OFString *)description; -/*! +/** * @brief Replaces a class method with a class method from another class. * * @param selector The selector of the class method to replace * @param class_ The class from which the new class method should be taken * @return The old implementation */ + (nullable IMP)replaceClassMethod: (SEL)selector withMethodFromClass: (Class)class_; -/*! +/** * @brief Replaces an instance method with an instance method from another * class. * * @param selector The selector of the instance method to replace * @param class_ The class from which the new instance method should be taken @@ -692,11 +712,11 @@ * @return The old implementation */ + (nullable IMP)replaceInstanceMethod: (SEL)selector withMethodFromClass: (Class)class_; -/*! +/** * @brief Adds all methods from the specified class to the class that is the * receiver. * * Methods implemented by the receiving class itself will not be overridden, * however methods implemented by its superclass will. Therefore it behaves @@ -712,41 +732,41 @@ * * @param class_ The class from which the instance methods should be inherited */ + (void)inheritMethodsFromClass: (Class)class_; -/*! +/** * @brief Try to resolve the specified class method. * * This method is called if a class method was not found, so that an * implementation can be provided at runtime. * * @return Whether the method has been added to the class */ + (bool)resolveClassMethod: (SEL)selector; -/*! +/** * @brief Try to resolve the specified instance method. * * This method is called if an instance method was not found, so that an * implementation can be provided at runtime. * * @return Whether the method has been added to the class */ + (bool)resolveInstanceMethod: (SEL)selector; -/*! +/** * @brief Returns the class. * * This method exists so that classes can be used in collections requiring * conformance to the OFCopying protocol. * * @return The class of the object */ + (id)copy; -/*! +/** * @brief Initializes an already allocated object. * * Derived classes may override this, but need to use the following pattern: * @code * self = [super init]; @@ -775,20 +795,20 @@ * * @return An initialized object */ - (instancetype)init; -/*! +/** * @brief Returns the method signature for the specified selector. * * @param selector The selector for which the method signature should be * 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 @@ -795,11 +815,11 @@ * @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. * @@ -809,11 +829,11 @@ * 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. * @@ -822,11 +842,11 @@ * 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. * @@ -837,11 +857,11 @@ */ - (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. * @@ -850,11 +870,11 @@ * @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. @@ -866,38 +886,38 @@ */ - (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. * * This also frees all memory in its memory pool. */ - (void)dealloc; -/*! +/** * @brief Performs the specified selector after the specified delay. * * @param selector The selector to perform * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector with the specified object after the * specified delay. * * @param selector The selector to perform * @param object The object that is passed to the method specified by the @@ -906,11 +926,11 @@ */ - (void)performSelector: (SEL)selector withObject: (nullable id)object afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector with the specified objects after the * specified delay. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the @@ -922,11 +942,11 @@ - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector with the specified objects after the * specified delay. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the @@ -941,11 +961,11 @@ withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector with the specified objects after the * specified delay. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the @@ -964,11 +984,11 @@ withObject: (nullable id)object3 withObject: (nullable id)object4 afterDelay: (of_time_interval_t)delay; # ifdef OF_HAVE_THREADS -/*! +/** * @brief Performs the specified selector on the specified thread. * * @param selector The selector to perform * @param thread The thread on which to perform the selector * @param waitUntilDone Whether to wait until the perform finished @@ -975,11 +995,11 @@ */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified object. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -990,11 +1010,11 @@ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified objects. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1008,11 +1028,11 @@ onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified objects. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1029,11 +1049,11 @@ withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified objects. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1053,20 +1073,20 @@ withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the main thread. * * @param selector The selector to perform * @param waitUntilDone Whether to wait until the perform finished */ - (void)performSelectorOnMainThread: (SEL)selector waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the main thread with the specified * object. * * @param selector The selector to perform * @param object The object that is passed to the method specified by the @@ -1075,11 +1095,11 @@ */ - (void)performSelectorOnMainThread: (SEL)selector withObject: (nullable id)object waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the main thread with the specified * objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the @@ -1091,11 +1111,11 @@ - (void)performSelectorOnMainThread: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the main thread with the specified * objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the @@ -1110,11 +1130,11 @@ withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the main thread with the specified * objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the @@ -1132,11 +1152,11 @@ withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 waitUntilDone: (bool)waitUntilDone; -/*! +/** * @brief Performs the specified selector on the specified thread after the * specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1144,11 +1164,11 @@ */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified object after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1159,11 +1179,11 @@ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified objects after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1177,11 +1197,11 @@ onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified objects after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1198,11 +1218,11 @@ withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 afterDelay: (of_time_interval_t)delay; -/*! +/** * @brief Performs the specified selector on the specified thread with the * specified objects after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -1223,11 +1243,11 @@ withObject: (nullable id)object3 withObject: (nullable id)object4 afterDelay: (of_time_interval_t)delay; # endif -/*! +/** * @brief This method is called when @ref resolveClassMethod: or * @ref resolveInstanceMethod: returned false. It should return a target * to which the message should be forwarded. * * @note When the message should not be forwarded, you should not return `nil`, @@ -1236,11 +1256,11 @@ * * @return The target to forward the message to */ - (nullable id)forwardingTargetForSelector: (SEL)selector; -/*! +/** * @brief Handles messages which are not understood by the receiver. * * @warning If you override this method, you must make sure that it never * returns! * @@ -1251,17 +1271,17 @@ #else typedef void OFObject; #endif #ifdef __OBJC__ -/*! +/** * @protocol OFCopying OFObject.h ObjFW/OFObject.h * * @brief A protocol for the creation of copies. */ @protocol OFCopying -/*! +/** * @brief Copies the object. * * For classes which can be immutable or mutable, this returns an immutable * copy. If only a mutable version of the class exists, it creates a mutable * copy. @@ -1269,36 +1289,36 @@ * @return A copy of the object */ - (id)copy; @end -/*! +/** * @protocol OFMutableCopying OFObject.h ObjFW/OFObject.h * * @brief A protocol for the creation of mutable copies. * * This protocol is implemented by objects that can be mutable and immutable * and allows returning a mutable copy. */ @protocol OFMutableCopying -/*! +/** * @brief Creates a mutable copy of the object. * * @return A mutable copy of the object */ - (id)mutableCopy; @end -/*! +/** * @protocol OFComparing OFObject.h ObjFW/OFObject.h * * @brief A protocol for comparing objects. * * This protocol is implemented by objects that can be compared. */ @protocol OFComparing -/*! +/** * @brief Compares the object with another object. * * @param object An object to compare the object to * @return The result of the comparison */ @@ -1310,10 +1330,15 @@ extern "C" { #endif #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_, + void *_Nullable bytes); +extern void *_Nullable objc_destructInstance(id _Nullable object); +# endif #endif extern id of_alloc_object(Class class_, size_t extraSize, size_t extraAlignment, void *_Nullable *_Nullable extra); extern void OF_NO_RETURN_FUNC of_method_not_found(id self, SEL _cmd); #ifndef OF_AMIGAOS @@ -1320,10 +1345,14 @@ extern uint32_t of_hash_seed; #else extern uint32_t *_Nonnull of_hash_seed_ref(void); # define of_hash_seed (*of_hash_seed_ref()) #endif +/* These do *NOT* provide cryptographically secure randomness! */ +extern uint16_t of_random16(void); +extern uint32_t of_random32(void); +extern uint64_t of_random64(void); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -24,10 +24,14 @@ #include #ifdef OF_APPLE_RUNTIME # include #endif + +#ifdef HAVE_GETRANDOM +# include +#endif #import "OFObject.h" #import "OFArray.h" #import "OFLocale.h" #import "OFMethodSignature.h" @@ -113,10 +117,85 @@ of_hash_seed_ref(void) { return &of_hash_seed; } #endif + +#if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM) +static void +initRandom(void) +{ + struct timeval tv; + +# ifdef HAVE_RANDOM + gettimeofday(&tv, NULL); + srandom((unsigned)(tv.tv_sec ^ tv.tv_usec)); +# else + gettimeofday(&tv, NULL); + srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); +# endif +} +#endif + +uint16_t +of_random16(void) +{ +#if defined(HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(HAVE_GETRANDOM) + uint16_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + static of_once_t onceControl = OF_ONCE_INIT; + + of_once(&onceControl, initRandom); +# ifdef HAVE_RANDOM + return random() & 0xFFFF; +# else + return rand() & 0xFFFF; +# endif +#endif +} + +uint32_t +of_random32(void) +{ +#if defined(HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(HAVE_GETRANDOM) + uint32_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + return ((uint32_t)of_random16() << 16) | of_random16(); +#endif +} + +uint64_t +of_random64(void) +{ +#if defined(HAVE_ARC4RANDOM_BUF) + uint64_t buffer; + + arc4random_buf(&buffer, sizeof(buffer)); + + return buffer; +#elif defined(HAVE_GETRANDOM) + uint64_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + return ((uint64_t)of_random32() << 32) | of_random32(); +#endif +} static const char * typeEncodingForSelector(Class class, SEL selector) { Method method; @@ -262,12 +341,17 @@ #endif objc_setEnumerationMutationHandler(enumerationMutationHandler); do { - of_hash_seed = of_random(); + of_hash_seed = of_random32(); } while (of_hash_seed == 0); + +#ifdef OF_OBJFW_RUNTIME + objc_setTaggedPointerSecret(sizeof(uintptr_t) == 4 + ? (uintptr_t)of_random32() : (uintptr_t)of_random64()); +#endif } + (void)unload { } Index: src/OFOptionsParser.h ================================================================== --- src/OFOptionsParser.h +++ src/OFOptionsParser.h @@ -20,25 +20,25 @@ @class OFMapTable; OF_ASSUME_NONNULL_BEGIN -/*! +/** * @struct of_options_parser_option_t OFOptionsParser.h ObjFW/OFOptionsParser.h * * @brief An option which can be parsed by an @ref OFOptionsParser. */ struct of_options_parser_option_t { - /*! The short version (e.g. `-v`) of the option or `\0` for none. */ + /** The short version (e.g. `-v`) of the option or `\0` for none. */ of_unichar_t shortOption; - /*! + /** * The long version (e.g. `--verbose`) of the option or `nil` for none. */ OFString *__unsafe_unretained _Nullable longOption; - /*! + /** * Whether the option takes an argument. * * 0 means it takes no argument.@n * 1 means it takes a required argument.@n * -1 means it takes an optional argument.@n @@ -46,25 +46,25 @@ * All other values are invalid and will throw an * @ref OFInvalidArgumentException. */ signed char hasArgument; - /*! + /** * An optional pointer to a bool that is set to whether the option has * been specified. */ bool *_Nullable isSpecifiedPtr; - /*! + /** * An optional pointer to an `OFString *` that is set to the * argument specified for the option or `nil` for no argument. */ OFString *__autoreleasing _Nullable *_Nullable argumentPtr; }; typedef struct of_options_parser_option_t of_options_parser_option_t; -/*! +/** * @class OFOptionsParser OFOptionsParser.h ObjFW/OFOptionsParser.h * * @brief A class for parsing the program options specified on the command line. */ OF_SUBCLASSING_RESTRICTED @@ -77,21 +77,21 @@ of_unichar_t _lastOption; OFString *_Nullable _lastLongOption, *_Nullable _argument; bool _done; } -/*! +/** * @brief The last parsed option. * * If @ref nextOption returned `?` or `:`, this returns the option which was * unknown or for which the argument was missing.@n * If this returns `-`, the last option is only available as a long option (see * lastLongOption). */ @property (readonly, nonatomic) of_unichar_t lastOption; -/*! +/** * @brief The long option for the last parsed option, or `nil` if the last * parsed option was not passed as a long option by the user. * * In case @ref nextOption returned `?`, this contains the unknown long * option.@n @@ -104,23 +104,23 @@ * user specified a long option, this only returns the long option if * it was actually specified as a long option by the user. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *lastLongOption; -/*! +/** * @brief The argument for the last parsed option, or `nil` if the last parsed * option takes no argument. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *argument; -/*! +/** * @brief The arguments following the last option. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *remainingArguments; -/*! +/** * @brief Creates a new OFOptionsParser which accepts the specified options. * * @param options An array of @ref of_options_parser_option_t specifying all * accepted options, terminated with an option whose short * option is `\0` and long option is `nil`. @@ -129,11 +129,11 @@ */ + (instancetype)parserWithOptions: (const of_options_parser_option_t *)options; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFOptionsParser so that it accepts * the specified options. * * @param options An array of @ref of_options_parser_option_t specifying all * accepted options, terminated with an option whose short @@ -142,11 +142,11 @@ * @return An initialized OFOptionsParser */ - (instancetype)initWithOptions: (const of_options_parser_option_t *)options OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Returns the next option. * * If the option is only available as a long option, `-` is returned. * Otherwise, the short option is returned, even if it was specified as a long * option.@n Index: src/OFPair.h ================================================================== --- src/OFPair.h +++ src/OFPair.h @@ -17,11 +17,11 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFPair OFPair.h ObjFW/OFPair.h * * @brief A class for storing a pair of two objects. */ @interface OFPair OF_GENERIC(FirstType, SecondType): OFObject #endif OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFSortedList OF_GENERIC(ObjectType); #ifdef OF_HAVE_THREADS @class OFMutex; @class OFCondition; @@ -36,27 +36,27 @@ #endif @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFTimer; @class OFDate; -/*! +/** * @brief A mode for an OFRunLoop. */ typedef OFConstantString *of_run_loop_mode_t; #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief The default mode for an OFRunLoop. */ extern const of_run_loop_mode_t of_run_loop_mode_default; #ifdef __cplusplus } #endif -/*! +/** * @class OFRunLoop OFRunLoop.h ObjFW/OFRunLoop.h * * @brief A class providing a run loop for the application and its processes. */ OF_SUBCLASSING_RESTRICTED @@ -75,42 +75,42 @@ @property (class, readonly, nullable, nonatomic) OFRunLoop *currentRunLoop; #endif @property OF_NULLABLE_PROPERTY (readonly, nonatomic) of_run_loop_mode_t currentMode; -/*! +/** * @brief Returns the run loop for the main thread. * * @return The run loop for the main thread */ + (nullable OFRunLoop *)mainRunLoop; -/*! +/** * @brief Returns the run loop for the current thread. * * @return The run loop for the current thread */ + (nullable OFRunLoop *)currentRunLoop; -/*! +/** * @brief Adds an OFTimer to the run loop. * * @param timer The timer to add */ - (void)addTimer: (OFTimer *)timer; -/*! +/** * @brief Adds an OFTimer to the run loop for the specified mode. * * @param timer The timer to add * @param mode The run loop mode in which to run the timer */ - (void)addTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode; #ifdef OF_AMIGAOS -/*! +/** * @brief Adds an Exec Signal to the run loop. * * If a signal is added multiple times, the specified methods will be performed * in the order added. * @@ -124,11 +124,11 @@ */ - (void)addExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector; -/*! +/** * @brief Adds an Exec Signal to the run loop for the specified mode. * * If a signal is added multiple times, the specified methods will be performed * in the order added. * @@ -144,11 +144,11 @@ - (void)addExecSignal: (ULONG)signal forMode: (of_run_loop_mode_t)mode target: (id)target selector: (SEL)selector; -/*! +/** * @brief Removes the specified Exec Signal with the specified target and * selector. * * @param signal The signal to remove * @param target The target which was specified when adding the signal @@ -156,11 +156,11 @@ */ - (void)removeExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector; -/*! +/** * @brief Removes the specified Exec Signal from the specified mode with the * specified target and selector. * * @param signal The signal to remove * @param mode The run loop mode to which the signal was added @@ -171,35 +171,35 @@ forMode: (of_run_loop_mode_t)mode target: (id)target selector: (SEL)selector; #endif -/*! +/** * @brief Starts the run loop. */ - (void)run; -/*! +/** * @brief Run the run loop until the specified deadline. * * @param deadline The date until which the run loop should run */ - (void)runUntilDate: (nullable OFDate *)deadline; -/*! +/** * @brief Run the run loop until an event or timer occurs or the specified * deadline is reached. * * @param mode The mode in which to run the run loop * @param deadline The date until which the run loop should run at the longest */ - (void)runMode: (of_run_loop_mode_t)mode beforeDate: (nullable OFDate *)deadline; -/*! +/** * @brief Stops the run loop. If there is still an operation being executed, it * is finished before the run loop stops. */ - (void)stop; @end OF_ASSUME_NONNULL_END Index: src/OFSCTPSocket.h ================================================================== --- src/OFSCTPSocket.h +++ src/OFSCTPSocket.h @@ -18,33 +18,33 @@ #import "OFSequencedPacketSocket.h" #import "OFRunLoop.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFSCTPSocket; @class OFString; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^of_sctp_socket_async_connect_block_t)(id _Nullable exception); #endif -/*! +/** * @protocol OFSCTPSocketDelegate OFSCTPSocket.h ObjFW/OFSCTPSocket.h * * A delegate for OFSCTPSocket. */ @protocol OFSCTPSocketDelegate @optional -/*! +/** * @brief A method which is called when a socket connected. * * @param socket The socket which connected * @param host The host connected to * @param port The port on the host connected to @@ -55,11 +55,11 @@ didConnectToHost: (OFString *)host port: (uint16_t)port exception: (nullable id)exception; @end -/*! +/** * @class OFSCTPSocket OFSCTPSocket.h ObjFW/OFSCTPSocket.h * * @brief A class which provides methods to create and use SCTP sockets in * one-to-one mode. * @@ -66,47 +66,47 @@ * To connect to a server, create a socket and connect it. * To create a server, create a socket, bind it and listen on it. */ @interface OFSCTPSocket: OFSequencedPacketSocket { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSCTPSocket, 4) } -/*! +/** * @brief Whether sending packets can be delayed. Setting this to NO sets * SCTP_NODELAY on the socket. */ @property (nonatomic) bool canDelaySendingPackets; -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Connect the OFSCTPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to */ - (void)connectToHost: (OFString *)host port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFSCTPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFSCTPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param runLoopMode The run loop mode in which to perform the async connect @@ -114,11 +114,11 @@ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously connect the OFSCTPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param block The block to execute once the connection has been established @@ -125,11 +125,11 @@ */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port block: (of_sctp_socket_async_connect_block_t)block; -/*! +/** * @brief Asynchronously connect the OFSCTPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param runLoopMode The run loop mode in which to perform the async connect @@ -139,11 +139,11 @@ port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sctp_socket_async_connect_block_t)block; #endif -/*! +/** * @brief Bind the socket to the specified host and port. * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be Index: src/OFSHA1Hash.h ================================================================== --- src/OFSHA1Hash.h +++ src/OFSHA1Hash.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFSecureData; -/*! +/** * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h * * @brief A class which provides methods to create an SHA-1 hash. */ OF_SUBCLASSING_RESTRICTED Index: src/OFSHA224Hash.h ================================================================== --- src/OFSHA224Hash.h +++ src/OFSHA224Hash.h @@ -17,15 +17,15 @@ #import "OFSHA224Or256Hash.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSHA224Hash OFSHA224Hash.h ObjFW/OFSHA224Hash.h * * @brief A class which provides methods to create an SHA-224 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFSHA224Hash: OFSHA224Or256Hash @end OF_ASSUME_NONNULL_END Index: src/OFSHA224Or256Hash.h ================================================================== --- src/OFSHA224Or256Hash.h +++ src/OFSHA224Or256Hash.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFSecureData; -/*! +/** * @class OFSHA224Or256Hash OFSHA224Or256Hash.h ObjFW/OFSHA224Or256Hash.h * * @brief A base class for SHA-224 and SHA-256. */ @interface OFSHA224Or256Hash: OFObject @@ -41,10 +41,10 @@ size_t bufferLength; } *_iVars; @private bool _allowsSwappableMemory; bool _calculated; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSHA224Or256Hash, 4) } @end OF_ASSUME_NONNULL_END Index: src/OFSHA256Hash.h ================================================================== --- src/OFSHA256Hash.h +++ src/OFSHA256Hash.h @@ -17,15 +17,15 @@ #import "OFSHA224Or256Hash.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSHA256Hash OFSHA256Hash.h ObjFW/OFSHA256Hash.h * * @brief A class which provides methods to create an SHA-256 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFSHA256Hash: OFSHA224Or256Hash @end OF_ASSUME_NONNULL_END Index: src/OFSHA384Hash.h ================================================================== --- src/OFSHA384Hash.h +++ src/OFSHA384Hash.h @@ -17,15 +17,15 @@ #import "OFSHA384Or512Hash.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSHA384Hash OFSHA384Hash.h ObjFW/OFSHA384Hash.h * * @brief A class which provides methods to create an SHA-384 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFSHA384Hash: OFSHA384Or512Hash @end OF_ASSUME_NONNULL_END Index: src/OFSHA384Or512Hash.h ================================================================== --- src/OFSHA384Or512Hash.h +++ src/OFSHA384Or512Hash.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFSecureData; -/*! +/** * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h * * @brief A base class for SHA-384 and SHA-512. */ @interface OFSHA384Or512Hash: OFObject @@ -41,10 +41,10 @@ size_t bufferLength; } *_iVars; @private bool _allowsSwappableMemory; bool _calculated; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSHA384Or512Hash, 4) } @end OF_ASSUME_NONNULL_END Index: src/OFSHA512Hash.h ================================================================== --- src/OFSHA512Hash.h +++ src/OFSHA512Hash.h @@ -17,15 +17,15 @@ #import "OFSHA384Or512Hash.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSHA512Hash OFSHA512Hash.h ObjFW/OFSHA512Hash.h * * @brief A class which provides methods to create an SHA-512 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFSHA512Hash: OFSHA384Or512Hash @end OF_ASSUME_NONNULL_END Index: src/OFSPXSocket.h ================================================================== --- src/OFSPXSocket.h +++ src/OFSPXSocket.h @@ -18,33 +18,33 @@ #import "OFSequencedPacketSocket.h" #import "OFRunLoop.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFSPXSocket; @class OFString; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^of_spx_socket_async_connect_block_t)(id _Nullable exception); #endif -/*! +/** * @protocol OFSPXSocketDelegate OFSPXSocket.h ObjFW/OFSPXSocket.h * * A delegate for OFSPXSocket. */ @protocol OFSPXSocketDelegate @optional -/*! +/** * @brief A method which is called when a socket connected. * * @param socket The socket which connected * @param node The node the socket connected to * @param network The network of the node the socket connected to @@ -57,11 +57,11 @@ network: (uint32_t)network port: (uint16_t)port exception: (nullable id)exception; @end -/*! +/** * @class OFSPXSocket OFSPXSocket.h ObjFW/OFSPXSocket.h * * @brief A class which provides methods to create and use SPX sockets. * * @note If you want to use SPX in streaming mode instead of in message mode, @@ -70,23 +70,23 @@ * To connect to a server, create a socket and connect it. * To create a server, create a socket, bind it and listen on it. */ @interface OFSPXSocket: OFSequencedPacketSocket { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSPXSocket, 4) } -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to @@ -94,11 +94,11 @@ */ - (void)connectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to @@ -106,11 +106,11 @@ */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to @@ -121,11 +121,11 @@ network: (uint32_t)network port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to @@ -135,11 +135,11 @@ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port block: (of_spx_socket_async_connect_block_t)block; -/*! +/** * @brief Asynchronously connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to @@ -152,11 +152,11 @@ port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_spx_socket_async_connect_block_t)block; #endif -/*! +/** * @brief Bind the socket to the specified network, node and port. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. * @return The address on which this socket can be reached Index: src/OFSPXStreamSocket.h ================================================================== --- src/OFSPXStreamSocket.h +++ src/OFSPXStreamSocket.h @@ -18,35 +18,35 @@ #import "OFStreamSocket.h" #import "OFRunLoop.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFSPXStreamSocket; @class OFString; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^of_spx_stream_socket_async_connect_block_t)( id _Nullable exception); #endif -/*! +/** * @protocol OFSPXStreamSocketDelegate OFSPXStreamSocket.h \ * ObjFW/OFSPXStreamSocket.h * * A delegate for OFSPXStreamSocket. */ @protocol OFSPXStreamSocketDelegate @optional -/*! +/** * @brief A method which is called when a socket connected. * * @param socket The socket which connected * @param node The node the socket connected to * @param network The network of the node the socket connected to @@ -59,11 +59,11 @@ network: (uint32_t)network port: (uint16_t)port exception: (nullable id)exception; @end -/*! +/** * @class OFSPXStreamSocket OFSPXStreamSocket.h ObjFW/OFSPXStreamSocket.h * * @brief A class which provides methods to create and use SPX stream sockets. * * @note If you want to use SPX in message mode instead of in streaming mode, @@ -72,23 +72,23 @@ * To connect to a server, create a socket and connect it. * To create a server, create a socket, bind it and listen on it. */ @interface OFSPXStreamSocket: OFStreamSocket { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSPXStreamSocket, 4) } -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Connect the OFSPXStreamSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to @@ -96,11 +96,11 @@ */ - (void)connectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFSPXStreamSocket to the specified * destination. * * @param node The node to connect to * @param network The network on which the node to connect to is @@ -109,11 +109,11 @@ */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFSPXStreamSocket to the specified * destination. * * @param node The node to connect to * @param network The network on which the node to connect to is @@ -125,11 +125,11 @@ network: (uint32_t)network port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously connect the OFSPXStreamSocket to the specified * destination. * * @param node The node to connect to * @param network The network on which the node to connect to is @@ -140,11 +140,11 @@ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port block: (of_spx_stream_socket_async_connect_block_t)block; -/*! +/** * @brief Asynchronously connect the OFSPXStreamSocket to the specified * destination. * * @param node The node to connect to * @param network The network on which the node to connect to is @@ -158,11 +158,11 @@ port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_spx_stream_socket_async_connect_block_t)block; #endif -/*! +/** * @brief Bind the socket to the specified network, node and port. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. * @return The address on which this socket can be reached Index: src/OFSandbox.h ================================================================== --- src/OFSandbox.h +++ src/OFSandbox.h @@ -17,23 +17,23 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFPair OF_GENERIC(FirstType, SecondType); -/*! +/** * @brief An @ref OFPair for a path to unveil, with the first string being the * path and the second the permissions. */ typedef OFPair OF_GENERIC(OFString *, OFString *) *of_sandbox_unveil_path_t; -/*! +/** * @class OFSandbox OFSandbox.h ObjFW/OFSandbox.h * * @brief A class which describes a sandbox for the application. */ @interface OFSandbox: OFObject @@ -69,184 +69,184 @@ unsigned int _allowsUnveil: 1; unsigned int _returnsErrors: 1; OFMutableArray OF_GENERIC(of_sandbox_unveil_path_t) *_unveiledPaths; @public size_t _unveiledPathsIndex; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSandbox, 4) } -/*! +/** * @brief Allows IO operations on previously allocated file descriptors. */ @property (nonatomic) bool allowsStdIO; -/*! +/** * @brief Allows read access to the file system. */ @property (nonatomic) bool allowsReadingFiles; -/*! +/** * @brief Allows write access to the file system. */ @property (nonatomic) bool allowsWritingFiles; -/*! +/** * @brief Allows creating files in the file system. */ @property (nonatomic) bool allowsCreatingFiles; -/*! +/** * @brief Allows creating special files in the file system. */ @property (nonatomic) bool allowsCreatingSpecialFiles; -/*! +/** * @brief Allows creating, reading and writing temporary files in `/tmp`. */ @property (nonatomic) bool allowsTemporaryFiles; -/*! +/** * @brief Allows using IP sockets. */ @property (nonatomic) bool allowsIPSockets; -/*! +/** * @brief Allows multicast sockets. */ @property (nonatomic) bool allowsMulticastSockets; -/*! +/** * @brief Allows explicit changes to file attributes. */ @property (nonatomic) bool allowsChangingFileAttributes; -/*! +/** * @brief Allows changing ownership of files. */ @property (nonatomic) bool allowsFileOwnerChanges; -/*! +/** * @brief Allows file locks. */ @property (nonatomic) bool allowsFileLocks; -/*! +/** * @brief Allows UNIX sockets. */ @property (nonatomic) bool allowsUNIXSockets; -/*! +/** * @brief Allows syscalls necessary for DNS lookups. */ @property (nonatomic) bool allowsDNS; -/*! +/** * @brief Allows to look up users and groups. */ @property (nonatomic) bool allowsUserDatabaseReading; -/*! +/** * @brief Allows sending file descriptors via sendmsg(). */ @property (nonatomic) bool allowsFileDescriptorSending; -/*! +/** * @brief Allows receiving file descriptors via recvmsg(). */ @property (nonatomic) bool allowsFileDescriptorReceiving; -/*! +/** * @brief Allows MTIOCGET and MTIOCTOP operations on tape devices. */ @property (nonatomic) bool allowsTape; -/*! +/** * @brief Allows read-write operations and ioctls on the TTY. */ @property (nonatomic) bool allowsTTY; -/*! +/** * @brief Allows various process relationshop operations. */ @property (nonatomic) bool allowsProcessOperations; -/*! +/** * @brief Allows execve(). */ @property (nonatomic) bool allowsExec; -/*! +/** * @brief Allows PROT_EXEC for `mmap()` and `mprotect()`. */ @property (nonatomic) bool allowsProtExec; -/*! +/** * @brief Allows `settime()`. */ @property (nonatomic) bool allowsSetTime; -/*! +/** * @brief Allows introspection of processes on the system. */ @property (nonatomic) bool allowsPS; -/*! +/** * @brief Allows introspection of the system's virtual memory. */ @property (nonatomic) bool allowsVMInfo; -/*! +/** * @brief Allows changing the rights of process, for example the UID. */ @property (nonatomic) bool allowsChangingProcessRights; -/*! +/** * @brief Allows certain ioctls on the PF device. */ @property (nonatomic) bool allowsPF; -/*! +/** * @brief Allows certain ioctls on audio devices. */ @property (nonatomic) bool allowsAudio; -/*! +/** * @brief Allows BIOCGSTATS to collect statistics from a BPF device. */ @property (nonatomic) bool allowsBPF; -/*! +/** * @brief Allows unveiling more paths. */ @property (nonatomic) bool allowsUnveil; -/*! +/** * @brief Returns errors instead of killing the process. */ @property (nonatomic) bool returnsErrors; #ifdef OF_HAVE_PLEDGE -/*! +/** * The string for OpenBSD's pledge() call. * * @warning Only available on systems with the pledge() call! */ @property (readonly, nonatomic) OFString *pledgeString; #endif -/*! +/** * @brief A list of unveiled paths. */ @property (readonly, nonatomic) OFArray OF_GENERIC(of_sandbox_unveil_path_t) *unveiledPaths; -/*! +/** * @brief Create a new, autorelease OFSandbox. */ + (instancetype)sandbox; -/*! +/** * @brief "Unveils" the specified path, meaning that it becomes visible from * the sandbox with the specified permissions. * * @param path The path to unveil * @param permissions The permissions for the path. The following permissions Index: src/OFSecureData.h ================================================================== --- src/OFSecureData.h +++ src/OFSecureData.h @@ -17,11 +17,11 @@ #import "OFData.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSecureData OFSecureData.h ObjFW/OFSecureData.h * * @brief A class for storing arbitrary data in secure (non-swappable) memory, * securely wiping it when it gets deallocated. * @@ -36,24 +36,24 @@ { struct page *_page; bool _allowsSwappableMemory; } -/*! +/** * @brief Whether the data may be stored in swappable memory. */ @property (readonly, nonatomic) bool allowsSwappableMemory; -/*! +/** * @brief All items of the OFSecureData as a C array. * * Modifying the returned array directly is allowed and will change the contents * of the data. */ @property (readonly, nonatomic) void *mutableItems OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Preallocates the specified number of bytes for unswappable memory. * * This is useful to allocate unswappable memory before enabling a sandbox that * does not allow it anymore. * @@ -63,11 +63,11 @@ * * @param size The number of bytes of unswappable memory to preallocate */ + (void)preallocateUnswappableMemoryWithSize: (size_t)size; -/*! +/** * @brief Creates a new, autoreleased OFSecureData with count items of item * size 1, all set to zero. * * @param count The number of zero items the OFSecureData should contain * @param allowsSwappableMemory Whether the data may be stored in swappable @@ -75,11 +75,11 @@ * @return A new, autoreleased OFSecureData */ + (instancetype)dataWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory; -/*! +/** * @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 @@ -108,11 +108,11 @@ #endif + (instancetype)dataWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE; + (instancetype)dataWithStringRepresentation: (OFString *)string OF_UNAVAILABLE; + (instancetype)dataWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFSecureData with count items of * item size 1, all set to zero. * * @param count The number of zero items the OFSecureData should contain * @param allowsSwappableMemory Whether the data may be stored in swappable @@ -120,11 +120,11 @@ * @return An initialized OFSecureData */ - (instancetype)initWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory; -/*! +/** * @brief Initializes an already allocated 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 @@ -155,11 +155,11 @@ - (instancetype)initWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE; - (instancetype)initWithStringRepresentation: (OFString *)string OF_UNAVAILABLE; - (instancetype)initWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE; - (instancetype)initWithSerialization: (OFXMLElement *)element OF_UNAVAILABLE; -/*! +/** * @brief Returns a specific item of the OFSecureData. * * Modifying the returned item directly is allowed and will change the contents * of the data array. * @@ -166,11 +166,11 @@ * @param index The number of the item to return * @return The specified item of the OFSecureData */ - (void *)mutableItemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Checks the OFSecureData for equality to another object. * * If the specified object is a subclass of @ref OFData, the comparison is * performed in constant time. * @@ -177,11 +177,11 @@ * @param object The object which should be tested for equality * @return A boolean whether the OFSecureData is equal to the specified object */ - (bool)isEqual: (nullable id)object; -/*! +/** * @brief Zeroes the data. */ - (void)zero; - (OFString *)stringRepresentation OF_UNAVAILABLE; Index: src/OFSeekableStream.h ================================================================== --- src/OFSeekableStream.h +++ src/OFSeekableStream.h @@ -42,11 +42,11 @@ typedef off64_t of_offset_t; #else typedef off_t of_offset_t; #endif -/*! +/** * @class OFSeekableStream OFSeekableStream.h ObjFW/OFSeekableStream.h * * @brief A stream that supports seeking. * * @note If you want to subclass this, override @@ -55,14 +55,14 @@ * override this methods without the `lowlevel` prefix, you *will* break * caching, get broken results and seek to the wrong position! */ @interface OFSeekableStream: OFStream { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSeekableStream, 4) } -/*! +/** * @brief Seeks to the specified absolute offset. * * @param offset The offset in bytes * @param whence From where to seek.@n * Possible values are: @@ -74,11 +74,11 @@ * @return The new offset form the start of the file */ - (of_offset_t)seekToOffset: (of_offset_t)offset whence: (int)whence; -/*! +/** * @brief Seek the stream on the lowlevel. * * @warning Do not call this directly! * * @note Override this method with your actual seek implementation when Index: src/OFSequencedPacketSocket.h ================================================================== --- src/OFSequencedPacketSocket.h +++ src/OFSequencedPacketSocket.h @@ -21,17 +21,17 @@ #import "socket.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFData; @class OFSequencedPacketSocket; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when a packet has been received. * * @param length The length of the packet * @param exception An exception which occurred while receiving or `nil` on * success @@ -38,11 +38,11 @@ * @return A bool whether the same block should be used for the next receive */ typedef bool (^of_sequenced_packet_socket_async_receive_block_t)(size_t length, id _Nullable exception); -/*! +/** * @brief A block which is called when a packet has been sent. * * @param data The data which was sent * @param exception An exception which occurred while reading or `nil` on * success @@ -49,11 +49,11 @@ * @return The data to repeat the send with or nil if it should not repeat */ typedef OFData *_Nullable (^of_sequenced_packet_socket_async_send_data_block_t)( OFData *_Nonnull data, id _Nullable exception); -/*! +/** * @brief A block which is called when the socket accepted a connection. * * @param acceptedSocket The socket which has been accepted * @param exception An exception which occurred while accepting the socket or * `nil` on success @@ -62,19 +62,19 @@ */ typedef bool (^of_sequenced_packet_socket_async_accept_block_t)( OFSequencedPacketSocket *acceptedSocket, id _Nullable exception); #endif -/*! +/** * @protocol OFSequencedPacketSocketDelegate OFSequencedPacketSocket.h \ * ObjFW/OFSequencedPacketSocket.h * * @brief A delegate for OFSequencedPacketSocket. */ @protocol OFSequencedPacketSocketDelegate @optional -/*! +/** * @brief This method is called when a packet has been received. * * @param socket The sequenced packet socket which received a packet * @param buffer The buffer the packet has been written to * @param length The length of the packet @@ -85,11 +85,11 @@ - (bool)socket: (OFSequencedPacketSocket *)socket didReceiveIntoBuffer: (void *)buffer length: (size_t)length exception: (nullable id)exception; -/*! +/** * @brief This method is called when a packet has been sent. * * @param socket The sequenced packet socket which sent a packet * @param data The data which was sent * @param exception An exception that occurred while sending, or nil on success @@ -97,11 +97,11 @@ */ - (nullable OFData *)socket: (OFSequencedPacketSocket *)socket didSendData: (OFData *)data exception: (nullable id)exception; -/*! +/** * @brief A method which is called when a socket accepted a connection. * * @param socket The socket which accepted the connection * @param acceptedSocket The socket which has been accepted * @param exception An exception that occurred while accepting, or nil on @@ -111,11 +111,11 @@ - (bool)socket: (OFSequencedPacketSocket *)socket didAcceptSocket: (OFSequencedPacketSocket *)acceptedSocket exception: (nullable id)exception; @end -/*! +/** * @class OFSequencedPacketSocket OFSequencedPacketSocket.h \ * ObjFW/OFSequencedPacketSocket.h * * @brief A base class for sequenced packet sockets. * @@ -131,49 +131,49 @@ { of_socket_t _socket; bool _canBlock, _listening; of_socket_address_t _remoteAddress; id _Nullable _delegate; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSequencedPacketSocket, 4) } -/*! +/** * @brief Whether the socket can block. * * By default, a socket can block. */ @property (nonatomic) bool canBlock; -/*! +/** * @brief Whether the socket is a listening socket. */ @property (readonly, nonatomic, getter=isListening) bool listening; -/*! +/** * @brief The remote address. * * @note This only works for accepted sockets! */ @property (readonly, nonatomic) const of_socket_address_t *remoteAddress; -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Returns a new, autoreleased OFSequencedPacketSocket. * * @return A new, autoreleased OFSequencedPacketSocket */ + (instancetype)socket; -/*! +/** * @brief Receives a packet and stores it into the specified buffer. * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to @@ -181,11 +181,11 @@ * @return The length of the received packet */ - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length; -/*! +/** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * @@ -193,11 +193,11 @@ * @param length The length of the buffer */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length; -/*! +/** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * @@ -208,11 +208,11 @@ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * @@ -228,11 +228,11 @@ asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (of_sequenced_packet_socket_async_receive_block_t) block; -/*! +/** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * @@ -251,37 +251,37 @@ runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sequenced_packet_socket_async_receive_block_t) block; #endif -/*! +/** * @brief Sends the specified packet. * * @param buffer The buffer to send as a packet * @param length The length of the buffer */ - (void)sendBuffer: (const void *)buffer length: (size_t)length; -/*! +/** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet */ - (void)asyncSendData: (OFData *)data; -/*! +/** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet * @param runLoopMode The run loop mode in which to perform the async send */ - (void)asyncSendData: (OFData *)data runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil @@ -289,11 +289,11 @@ */ - (void)asyncSendData: (OFData *)data block: (of_sequenced_packet_socket_async_send_data_block_t) block; -/*! +/** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet * @param runLoopMode The run loop mode in which to perform the async send * @param block The block to call when the packet has been sent. It should @@ -304,53 +304,53 @@ runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sequenced_packet_socket_async_send_data_block_t) block; #endif -/*! +/** * @brief Listen on the socket. * * @param backlog Maximum length for the queue of pending connections. */ - (void)listenWithBacklog: (int)backlog; -/*! +/** * @brief Listen on the socket. */ - (void)listen; -/*! +/** * @brief Accept an incoming connection. * * @return An autoreleased sequenced packet socket for the accepted connection. */ - (instancetype)accept; -/*! +/** * @brief Asynchronously accept an incoming connection. */ - (void)asyncAccept; -/*! +/** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept */ - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously accept an incoming connection. * * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted * by the specified block as well. */ - (void)asyncAcceptWithBlock: (of_sequenced_packet_socket_async_accept_block_t)block; -/*! +/** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted @@ -358,18 +358,18 @@ */ - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sequenced_packet_socket_async_accept_block_t)block; #endif -/*! +/** * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; -/*! +/** * @brief Closes the socket so that it can neither receive nor send any more * datagrams. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFSerialization.h ================================================================== --- src/OFSerialization.h +++ src/OFSerialization.h @@ -21,26 +21,26 @@ #define OF_SERIALIZATION_NS @"https://objfw.nil.im/serialization" @class OFXMLElement; -/*! +/** * @protocol OFSerialization OFSerialization.h ObjFW/OFSerialization.h * * @brief A protocol for serializing objects. */ @protocol OFSerialization -/*! +/** * @brief The object serialized into an XML element. */ @property (readonly, nonatomic) OFXMLElement *XMLElementBySerializing; -/*! +/** * @brief Initializes the object with the specified XML element serialization. * * @param element An OFXMLElement with the serialized object * @return An initialized object */ - (instancetype)initWithSerialization: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END Index: src/OFSet.h ================================================================== --- src/OFSet.h +++ src/OFSet.h @@ -28,34 +28,34 @@ #import "OFCollection.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFArray OF_GENERIC(ObjectType); #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for enumerating an OFSet. * * @param object The current object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^of_set_enumeration_block_t)(id object, bool *stop); -/*! +/** * @brief A block for filtering an OFSet. * * @param object The object to inspect * @return Whether the object should be in the filtered set */ typedef bool (^of_set_filter_block_t)(id object); #endif -/*! +/** * @class OFSet OFSet.h ObjFW/OFSet.h * * @brief An abstract class for an unordered set of unique objects. * * @warning Do not mutate objects that are in a set! Changing the hash of @@ -67,96 +67,96 @@ @interface OFSet OF_GENERIC(ObjectType): OFObject #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif -/*! +/** * @brief An array of all objects in the set. */ @property (readonly, nonatomic) OFArray OF_GENERIC(ObjectType) *allObjects; -/*! +/** * @brief An arbitrary object in the set. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) ObjectType anyObject; -/*! +/** * @brief Creates a new set. * * @return A new, autoreleased set */ + (instancetype)set; -/*! +/** * @brief Creates a new set with the specified set. * * @param set The set to initialize the set with * @return A new, autoreleased set with the specified set */ + (instancetype)setWithSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Creates a new set with the specified array. * * @param array The array to initialize the set with * @return A new, autoreleased set with the specified array */ + (instancetype)setWithArray: (OFArray OF_GENERIC(ObjectType) *)array; -/*! +/** * @brief Creates a new set with the specified objects. * * @param firstObject The first object for the set * @return A new, autoreleased set with the specified objects */ + (instancetype)setWithObjects: (ObjectType)firstObject, ...; -/*! +/** * @brief Creates a new set with the specified objects. * * @param objects An array of objects for the set * @param count The number of objects in the specified array * @return A new, autoreleased set with the specified objects */ + (instancetype)setWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; -/*! +/** * @brief Initializes an already allocated set with the specified set. * * @param set The set to initialize the set with * @return An initialized set with the specified set */ - (instancetype)initWithSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Initializes an already allocated set with the specified array. * * @param array The array to initialize the set with * @return An initialized set with the specified array */ - (instancetype)initWithArray: (OFArray OF_GENERIC(ObjectType) *)array; -/*! +/** * @brief Initializes an already allocated set with the specified objects. * * @param firstObject The first object for the set * @return An initialized set with the specified objects */ - (instancetype)initWithObjects: (ObjectType)firstObject, ... OF_SENTINEL; -/*! +/** * @brief Initializes an already allocated set with the specified objects. * * @param objects An array of objects for the set * @param count The number of objects in the specified array * @return An initialized set with the specified objects */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; -/*! +/** * @brief Initializes an already allocated set with the specified object and * va_list. * * @param firstObject The first object for the set * @param arguments A va_list with the other objects @@ -163,63 +163,63 @@ * @return An initialized set with the specified object and va_list */ - (instancetype)initWithObject: (ObjectType)firstObject arguments: (va_list)arguments; -/*! +/** * @brief Returns whether the receiver is a subset of the specified set. * * @return Whether the receiver is a subset of the specified set */ - (bool)isSubsetOfSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Returns whether the receiver and the specified set have at least one * object in common. * * @return Whether the receiver and the specified set have at least one object * in common */ - (bool)intersectsSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Creates a new set which contains the objects which are in the * receiver, but not in the specified set. * * @param set The set whose objects will not be in the new set */ - (OFSet OF_GENERIC(ObjectType) *)setBySubtractingSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Creates a new set by creating the intersection of the receiver and * the specified set. * * @param set The set to intersect with */ - (OFSet OF_GENERIC(ObjectType) *)setByIntersectingWithSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Creates a new set by creating the union of the receiver and the * specified set. * * @param set The set to create the union with */ - (OFSet OF_GENERIC(ObjectType) *)setByAddingSet: (OFSet OF_GENERIC(ObjectType) *)set; -/*! +/** * @brief Checks whether the set contains an object equal to the specified * object. * * @param object The object which is checked for being in the set * @return A boolean whether the set contains the specified object */ - (bool)containsObject: (ObjectType)object; -/*! +/** * @brief Returns the value for the specified key * * A new set with the value for the specified key for each object is returned. * * The special key `@count` can be used to retrieve the count as an OFNumber. @@ -229,11 +229,11 @@ * @param key The key of the value to return * @return The value for the specified key */ - (nullable id)valueForKey: (OFString *)key; -/*! +/** * @brief Set the value for the specified key * * @ref setValue:forKey: is called for each object. * * @note A @ref OFNull value is translated to nil! @@ -243,18 +243,18 @@ */ - (void)setValue: (nullable id)value forKey: (OFString *)key; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Executes a block for each object in the set. * * @param block The block to execute for each object in the set */ - (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block; -/*! +/** * @brief Creates a new set, only containing the objects for which the block * returns true. * * @param block A block which determines if the object should be in the new set * @return A new, autoreleased OFSet Index: src/OFSettings.h ================================================================== --- src/OFSettings.h +++ src/OFSettings.h @@ -20,11 +20,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFArray OF_GENERIC(ObjectType); -/*! +/** * @class OFSettings OFSettings.h ObjFW/OFSettings.h * * Paths are delimited by dots, for example `category.subcategory.key`. * * @note The behaviour when accessing a path with a different type than it has @@ -34,20 +34,20 @@ * @brief A class for storing and retrieving settings */ @interface OFSettings: OFObject { OFString *_applicationName; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSettings, 4) } -/*! +/** * @brief The name of the application whose settings are accessed by the * instance. */ @property (readonly, nonatomic) OFString *applicationName; -/*! +/** * @brief Create a new OFSettings instance for the application with the * specified name. * * @param applicationName The name of the application whose settings should be * accessed @@ -55,11 +55,11 @@ */ + (instancetype)settingsWithApplicationName: (OFString *)applicationName; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFSettings instance with the * specified application name. * * @param applicationName The name of the application whose settings should be * accessed @@ -66,74 +66,74 @@ * @return An initialized OFSettings instance */ - (instancetype)initWithApplicationName: (OFString *)applicationName OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Sets the specified path to the specified string. * * @param string The string to set * @param path The path to store the string at */ - (void)setString: (OFString *)string forPath: (OFString *)path; -/*! +/** * @brief Sets the specified path to the specified integer. * * @param integer The integer to set * @param path The path to store the integer at */ -- (void)setInteger: (intmax_t)integer +- (void)setInteger: (long long)integer forPath: (OFString *)path; -/*! +/** * @brief Sets the specified path to the specified bool. * * @param bool_ The bool to set * @param path The path to store the bool at */ - (void)setBool: (bool)bool_ forPath: (OFString *)path; -/*! +/** * @brief Sets the specified path to the specified float. * * @param float_ The float to set * @param path The path to store the float at */ - (void)setFloat: (float)float_ forPath: (OFString *)path; -/*! +/** * @brief Sets the specified path to the specified double. * * @param double_ The double to set * @param path The path to store the double at */ - (void)setDouble: (double)double_ forPath: (OFString *)path; -/*! +/** * @brief Sets the specified path to the specified array of strings. * * @param array The array of strings to set * @param path The path to store the array of strings at */ - (void)setArray: (OFArray OF_GENERIC(OFString *) *)array forPath: (OFString *)path; -/*! +/** * @brief Returns the string for the specified path, or `nil` if the path does * not exist. * * @param path The path for which the string value should be returned * @return The string value of the specified path */ - (nullable OFString *)stringForPath: (OFString *)path; -/*! +/** * @brief Returns the string for the specified path, or the default value if * the path does not exist. * * @param path The path for which the string value should be returned * @param defaultValue The default value to return if the path does not exist @@ -140,22 +140,22 @@ * @return The string value of the specified path */ - (nullable OFString *)stringForPath: (OFString *)path defaultValue: (nullable OFString *)defaultValue; -/*! +/** * @brief Returns the integer for the specified path, or the default value if * the path does not exist. * * @param path The path for which the integer value should be returned * @param defaultValue The default value to return if the path does not exist * @return The integer value of the specified path */ -- (intmax_t)integerForPath: (OFString *)path - defaultValue: (intmax_t)defaultValue; +- (long long)integerForPath: (OFString *)path + defaultValue: (long long)defaultValue; -/*! +/** * @brief Returns the bool for the specified path, or the default value if the * path does not exist. * * @param path The path for which the bool value should be returned * @param defaultValue The default value to return if the path does not exist @@ -162,11 +162,11 @@ * @return The bool value of the specified path */ - (bool)boolForPath: (OFString *)path defaultValue: (bool)defaultValue; -/*! +/** * @brief Returns the float for the specified path, or the default value if the * path does not exist. * * @param path The path for which the float value should be returned * @param defaultValue The default value to return if the path does not exist @@ -173,11 +173,11 @@ * @return The float value of the specified path */ - (float)floatForPath: (OFString *)path defaultValue: (float)defaultValue; -/*! +/** * @brief Returns the double for the specified path, or the default value if * the path does not exist. * * @param path The path for which the double value should be returned * @param defaultValue The default value to return if the path does not exist @@ -184,27 +184,27 @@ * @return The double value of the specified path */ - (double)doubleForPath: (OFString *)path defaultValue: (double)defaultValue; -/*! +/** * @brief Returns the array of strings for the specified path, or an empty * array if the path does not exist. * * @param path The path for which the array of strings should be returned * @return The array of strings of the specified path */ - (OFArray OF_GENERIC(OFString *) *)arrayForPath: (OFString *)path; -/*! +/** * @brief Removes the value for the specified path. * * @param path The path for which the value should be removed */ - (void)removeValueForPath: (OFString *)path; -/*! +/** * @brief Saves the settings to disk. * * @warning Some backends might save the settings instantly, others might not * save them before calling this method for performance reasons. You * should always call this method after doing a bunch of changes, no Index: src/OFSettings.m ================================================================== --- src/OFSettings.m +++ src/OFSettings.m @@ -68,11 +68,11 @@ forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } -- (void)setInteger: (intmax_t)integer +- (void)setInteger: (long long)integer forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } @@ -110,12 +110,12 @@ defaultValue: (OFString *)defaultValue { OF_UNRECOGNIZED_SELECTOR } -- (intmax_t)integerForPath: (OFString *)path - defaultValue: (intmax_t)defaultValue +- (long long)integerForPath: (OFString *)path + defaultValue: (long long)defaultValue { OF_UNRECOGNIZED_SELECTOR } - (bool)boolForPath: (OFString *)path Index: src/OFSortedList.h ================================================================== --- src/OFSortedList.h +++ src/OFSortedList.h @@ -17,11 +17,11 @@ #import "OFList.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSortedList OFSortedList.h ObjFW/OFSortedList.h * * @brief A class which provides easy to use sorted double-linked lists. * * @warning Because the list is sorted, all methods inserting an object at a @@ -30,11 +30,11 @@ @interface OFSortedList OF_GENERIC(ObjectType): OFList OF_GENERIC(ObjectType) #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFSortedList, 4) } - (of_list_object_t *)appendObject: (ObjectType)object OF_UNAVAILABLE; - (of_list_object_t *)prependObject: (ObjectType)object OF_UNAVAILABLE; - (of_list_object_t *)insertObject: (ObjectType)object @@ -42,11 +42,11 @@ OF_UNAVAILABLE; - (of_list_object_t *)insertObject: (ObjectType)object afterListObject: (of_list_object_t *)listObject OF_UNAVAILABLE; -/*! +/** * @brief Inserts the object to the list while keeping the list sorted. * * @param object The object to insert * @return The list object for the object just added */ Index: src/OFStdIOStream.h ================================================================== --- src/OFStdIOStream.h +++ src/OFStdIOStream.h @@ -22,15 +22,15 @@ # include #endif OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFColor; -/*! +/** * @class OFStdIOStream OFStdIOStream.h ObjFW/OFStdIOStream.h * * @brief A class for providing standard input, output and error as OFStream. * * The global variables @ref of_stdin, @ref of_stdout and @ref of_stderr are @@ -51,80 +51,80 @@ bool _closable; #endif bool _atEndOfStream; } -/*! +/** * @brief Whether there is an underlying terminal. */ @property (readonly, nonatomic) bool hasTerminal; -/*! +/** * @brief The number of columns, or -1 if there is no underlying terminal or * the number of columns could not be queried. */ @property (readonly, nonatomic) int columns; -/*! +/** * @brief The number of rows, or -1 if there is no underlying terminal or the * number of rows could not be queried. */ @property (readonly, nonatomic) int rows; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Sets the foreground color on the underlying terminal. Does nothing if * there is no underlying terminal or colors are unsupported. * * @param color The foreground color to set */ - (void)setForegroundColor: (OFColor *)color; -/*! +/** * @brief Sets the background color on the underlying terminal. Does nothing if * there is no underlying terminal or colors are unsupported. * * @param color The background color to set */ - (void)setBackgroundColor: (OFColor *)color; -/*! +/** * @brief Resets all attributes (color, bold, etc.). Does nothing if there is * no underlying terminal. */ - (void)reset; -/*! +/** * @brief Clears the entire underlying terminal. Does nothing if there is no * underlying terminal. */ - (void)clear; -/*! +/** * @brief Erases the entire current line on the underlying terminal. Does * nothing if there is no underlying terminal. */ - (void)eraseLine; -/*! +/** * @brief Moves the cursor to the specified column in the current row. Does * nothing if there is no underlying terminal. * * @param column The column in the current row to move the cursor to */ - (void)setCursorColumn: (unsigned int)column; -/*! +/** * @brief Moves the cursor to the specified absolute position. Does nothing if * there is no underlying terminal. * * @param position The position to move the cursor to */ - (void)setCursorPosition: (of_point_t)position; -/*! +/** * @brief Moves the cursor to the specified relative position. Does nothing if * there is no underlying terminal. * * @param position The position to move the cursor to */ @@ -132,24 +132,24 @@ @end #ifdef __cplusplus extern "C" { #endif -/*! @file */ +/** @file */ #ifndef OF_AMIGAOS -/*! +/** * @brief The standard input as an OFStream. */ extern OFStdIOStream *_Nullable of_stdin; -/*! +/** * @brief The standard output as an OFStream. */ extern OFStdIOStream *_Nullable of_stdout; -/*! +/** * @brief The standard error as an OFStream. */ extern OFStdIOStream *_Nullable of_stderr; #else extern OFStdIOStream *_Nonnull *_Nullable of_stdin_ref(void); @@ -158,11 +158,11 @@ # define of_stdin (*of_stdin_ref()) # define of_stdout (*of_stdout_ref()) # define of_stderr (*of_stderr_ref()) #endif -/*! +/** * @brief Logs the specified printf-style format to @ref of_stderr. * * This prefixes the output with the date, timestamp, process name and PID and * allows `%@` as a printf-style formatted to print objects. */ Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -31,17 +31,17 @@ # import "OFKernelEventObserver.h" #endif OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFStream; @class OFData; #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_BLOCKS) -/*! +/** * @brief A block which is called when data was read asynchronously from a * stream. * * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on @@ -49,11 +49,11 @@ * @return A bool whether the same block should be used for the next read */ typedef bool (^of_stream_async_read_block_t)(size_t length, id _Nullable exception); -/*! +/** * @brief A block which is called when a line was read asynchronously from a * stream. * * @param line The line which has been read or `nil` when the end of stream * occurred @@ -62,11 +62,11 @@ * @return A bool whether the same block should be used for the next read */ typedef bool (^of_stream_async_read_line_block_t)(OFString *_Nullable line, id _Nullable exception); -/*! +/** * @brief A block which is called when data was written asynchronously to a * stream. * * @param data The data which was written to the stream * @param bytesWritten The number of bytes which have been written. This @@ -77,11 +77,11 @@ * @return The data to repeat the write with or nil if it should not repeat */ typedef OFData *_Nullable (^of_stream_async_write_data_block_t)( OFData *_Nonnull data, size_t bytesWritten, id _Nullable exception); -/*! +/** * @brief A block which is called when a string was written asynchronously to a * stream. * * @param string The string which was written to the stream * @param bytesWritten The number of bytes which have been written. This @@ -93,18 +93,18 @@ */ typedef OFString *_Nullable (^of_stream_async_write_string_block_t)( OFString *_Nonnull string, size_t bytesWritten, id _Nullable exception); #endif -/*! +/** * @protocol OFStreamDelegate OFStream.h ObjFW/OFStream.h * * A delegate for OFStream. */ @protocol OFStreamDelegate @optional -/*! +/** * @brief This method is called when data was read asynchronously from a * stream. * * @param stream The stream on which data was read * @param buffer A buffer with the data that has been read @@ -115,11 +115,11 @@ - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (nullable id)exception; -/*! +/** * @brief This method is called when a line was read asynchronously from a * stream. * * @param stream The stream on which a line was read * @param line The line which has been read or `nil` when the end of stream @@ -129,11 +129,11 @@ */ - (bool)stream: (OFStream *)stream didReadLine: (nullable OFString *)line exception: (nullable id)exception; -/*! +/** * @brief This method is called when data was written asynchronously to a * stream. * * @param stream The stream to which data was written * @param data The data which was written to the stream @@ -146,11 +146,11 @@ - (nullable OFData *)stream: (OFStream *)stream didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (nullable id)exception; -/*! +/** * @brief This method is called when a string was written asynchronously to a * stream. * * @param stream The stream to which a string was written * @param string The string which was written to the stream @@ -166,11 +166,11 @@ encoding: (of_string_encoding_t)encoding bytesWritten: (size_t)bytesWritten exception: (nullable id)exception; @end -/*! +/** * @class OFStream OFStream.h ObjFW/OFStream.h * * @brief A base class for different types of streams. * * @warning Even though the OFCopying protocol is implemented, it does *not* @@ -197,46 +197,46 @@ #endif char *_Nullable _readBuffer, *_Nullable _readBufferMemory; char *_Nullable _writeBuffer; size_t _readBufferLength, _writeBufferLength; bool _buffersWrites, _waitingForDelimiter; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFStream, 4) } -/*! +/** * @brief Whether the end of the stream has been reached. */ @property (readonly, nonatomic, getter=isAtEndOfStream) bool atEndOfStream; -/*! +/** * @brief Whether writes are buffered. */ @property (nonatomic, nonatomic) bool buffersWrites; -/*! +/** * @brief Whether data is present in the internal read buffer. */ @property (readonly, nonatomic) bool hasDataInReadBuffer; -/*! +/** * @brief Whether the stream can block. * * By default, a stream can block. * On Win32, setting this currently only works for sockets! */ @property (nonatomic) bool canBlock; -/*! +/** * @brief The delegate for asynchronous operations on the stream. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Reads *at most* size bytes from the stream into a buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use * @ref readIntoBuffer:exactLength:. Note that a read can even return 0 bytes - @@ -251,11 +251,11 @@ * @return The number of bytes read */ - (size_t)readIntoBuffer: (void *)buffer length: (size_t)length; -/*! +/** * @brief Reads exactly the specified length bytes from the stream into a * buffer. * * Unlike @ref readIntoBuffer:length:, this method does not return when less * than the specified length has been read - instead, it waits until it got @@ -270,11 +270,11 @@ */ - (void)readIntoBuffer: (void *)buffer exactLength: (size_t)length; #ifdef OF_HAVE_SOCKETS -/*! +/** * @brief Asynchronously reads *at most* size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use @@ -293,11 +293,11 @@ * The buffer *must* be *at least* this big! */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length; -/*! +/** * @brief Asynchronously reads *at most* size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use @@ -318,11 +318,11 @@ */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode; -/*! +/** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:, this method does not call the * method when less than the specified length has been read - instead, it waits @@ -337,11 +337,11 @@ * The buffer *must* be *at least* this big! */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length; -/*! +/** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:, this method does not call the * method when less than the specified length has been read - instead, it waits @@ -359,11 +359,11 @@ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode; # ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously reads *at most* ref size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use @@ -388,11 +388,11 @@ */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block; -/*! +/** * @brief Asynchronously reads *at most* ref size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use @@ -419,11 +419,11 @@ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_async_read_block_t)block; -/*! +/** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke * the block when less than the specified length has been read - instead, it @@ -444,11 +444,11 @@ */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length block: (of_stream_async_read_block_t)block; -/*! +/** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke * the block when less than the specified length has been read - instead, it @@ -473,71 +473,71 @@ runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_async_read_block_t)block; # endif #endif -/*! +/** * @brief Reads a uint8_t from the stream. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint8_t from the stream */ - (uint8_t)readInt8; -/*! +/** * @brief Reads a uint16_t from the stream which is encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint16_t from the stream in native endianess */ - (uint16_t)readBigEndianInt16; -/*! +/** * @brief Reads a uint32_t from the stream which is encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint32_t from the stream in the native endianess */ - (uint32_t)readBigEndianInt32; -/*! +/** * @brief Reads a uint64_t from the stream which is encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint64_t from the stream in the native endianess */ - (uint64_t)readBigEndianInt64; -/*! +/** * @brief Reads a float from the stream which is encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A float from the stream in the native endianess */ - (float)readBigEndianFloat; -/*! +/** * @brief Reads a double from the stream which is encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A double from the stream in the native endianess */ - (double)readBigEndianDouble; -/*! +/** * @brief Reads the specified number of uint16_ts from the stream which are * encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -548,11 +548,11 @@ * @return The number of bytes read */ - (size_t)readBigEndianInt16sIntoBuffer: (uint16_t *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of uint32_ts from the stream which are * encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -563,11 +563,11 @@ * @return The number of bytes read */ - (size_t)readBigEndianInt32sIntoBuffer: (uint32_t *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of uint64_ts from the stream which are * encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -578,11 +578,11 @@ * @return The number of bytes read */ - (size_t)readBigEndianInt64sIntoBuffer: (uint64_t *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of floats from the stream which are encoded * in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -593,11 +593,11 @@ * @return The number of bytes read */ - (size_t)readBigEndianFloatsIntoBuffer: (float *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of doubles from the stream which are * encoded in big endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -608,61 +608,61 @@ * @return The number of bytes read */ - (size_t)readBigEndianDoublesIntoBuffer: (double *)buffer count: (size_t)count; -/*! +/** * @brief Reads a uint16_t from the stream which is encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint16_t from the stream in native endianess */ - (uint16_t)readLittleEndianInt16; -/*! +/** * @brief Reads a uint32_t from the stream which is encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint32_t from the stream in the native endianess */ - (uint32_t)readLittleEndianInt32; -/*! +/** * @brief Reads a uint64_t from the stream which is encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint64_t from the stream in the native endianess */ - (uint64_t)readLittleEndianInt64; -/*! +/** * @brief Reads a float from the stream which is encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A float from the stream in the native endianess */ - (float)readLittleEndianFloat; -/*! +/** * @brief Reads a double from the stream which is encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A double from the stream in the native endianess */ - (double)readLittleEndianDouble; -/*! +/** * @brief Reads the specified number of uint16_ts from the stream which are * encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -673,11 +673,11 @@ * @return The number of bytes read */ - (size_t)readLittleEndianInt16sIntoBuffer: (uint16_t *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of uint32_ts from the stream which are * encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -688,11 +688,11 @@ * @return The number of bytes read */ - (size_t)readLittleEndianInt32sIntoBuffer: (uint32_t *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of uint64_ts from the stream which are * encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -703,11 +703,11 @@ * @return The number of bytes read */ - (size_t)readLittleEndianInt64sIntoBuffer: (uint64_t *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of floats from the stream which are * encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -718,11 +718,11 @@ * @return The number of bytes read */ - (size_t)readLittleEndianFloatsIntoBuffer: (float *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of doubles from the stream which are * encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -733,11 +733,11 @@ * @return The number of bytes read */ - (size_t)readLittleEndianDoublesIntoBuffer: (double *)buffer count: (size_t)count; -/*! +/** * @brief Reads the specified number of items with an item size of 1 from the * stream and returns them as OFData. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -745,11 +745,11 @@ * @param count The number of items to read * @return OFData with count items. */ - (OFData *)readDataWithCount: (size_t)count; -/*! +/** * @brief Reads the specified number of items with the specified item size from * the stream and returns them as OFData. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! @@ -759,19 +759,19 @@ * @return OFData with count items. */ - (OFData *)readDataWithItemSize: (size_t)itemSize count: (size_t)count; -/*! +/** * @brief Returns OFData with all the remaining data of the stream. * * @return OFData with an item size of 1 with all the data of the stream until * the end of the stream is reached. */ - (OFData *)readDataUntilEndOfStream; -/*! +/** * @brief Reads a string with the specified length from the stream. * * If `\0` appears in the stream, the string will be truncated at the `\0` and * the rest of the bytes of the string will be lost. This way, reading from the * stream will not break because of a `\0` because the specified number of @@ -783,11 +783,11 @@ * @param length The length (in bytes) of the string to read from the stream * @return A string with the specified length */ - (OFString *)readStringWithLength: (size_t)length; -/*! +/** * @brief Reads a string with the specified encoding and length from the stream. * * If a `\0` appears in the stream, the string will be truncated at the `\0` * and the rest of the bytes of the string will be lost. This way, reading from * the stream will not break because of a `\0` because the specified number of @@ -801,19 +801,19 @@ * @return A string with the specified length */ - (OFString *)readStringWithLength: (size_t)length encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Reads until a newline, `\0` or end of stream occurs. * * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)readLine; -/*! +/** * @brief Reads with the specified encoding until a newline, `\0` or end of * stream occurs. * * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the end of the @@ -820,20 +820,20 @@ * stream has been reached. */ - (nullable OFString *)readLineWithEncoding: (of_string_encoding_t)encoding; #ifdef OF_HAVE_SOCKETS -/*! +/** * @brief Asynchronously reads until a newline, `\0`, end of stream or an * exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! */ - (void)asyncReadLine; -/*! +/** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! @@ -840,11 +840,11 @@ * * @param encoding The encoding used by the stream */ - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! @@ -854,11 +854,11 @@ */ - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding runLoopMode: (of_run_loop_mode_t)runLoopMode; # ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously reads until a newline, `\0`, end of stream or an * exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! @@ -869,11 +869,11 @@ * to handle the next line, you need to return false from the * block. */ - (void)asyncReadLineWithBlock: (of_stream_async_read_line_block_t)block; -/*! +/** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! @@ -886,11 +886,11 @@ * block. */ - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding block: (of_stream_async_read_line_block_t)block; -/*! +/** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! @@ -907,20 +907,20 @@ runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_async_read_line_block_t)block; # endif #endif -/*! +/** * @brief Tries to read a line from the stream (see @ref readLine) and returns * `nil` if no complete line has been received yet. * * @return The line that was read, autoreleased, or `nil` if the line is not * complete yet */ - (nullable OFString *)tryReadLine; -/*! +/** * @brief Tries to read a line from the stream with the specified encoding (see * @ref readLineWithEncoding:) and returns `nil` if no complete line has * been received yet. * * @param encoding The encoding used by the stream @@ -927,21 +927,21 @@ * @return The line that was read, autoreleased, or `nil` if the line is not * complete yet */ - (nullable OFString *)tryReadLineWithEncoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Reads until the specified string or `\0` is found or the end of * stream occurs. * * @param delimiter The delimiter * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)readTillDelimiter: (OFString *)delimiter; -/*! +/** * @brief Reads until the specified string or `\0` is found or the end of * stream occurs. * * @param delimiter The delimiter * @param encoding The encoding used by the stream @@ -949,11 +949,11 @@ * stream has been reached. */ - (nullable OFString *)readTillDelimiter: (OFString *)delimiter encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Tries to reads until the specified string or `\0` is found or the end * of stream (see @ref readTillDelimiter:) and returns `nil` if not * enough data has been received yet. * * @param delimiter The delimiter @@ -960,11 +960,11 @@ * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)tryReadTillDelimiter: (OFString *)delimiter; -/*! +/** * @brief Tries to read until the specified string or `\0` is found or the end * of stream occurs (see @ref readTillDelimiter:encoding:) and returns * `nil` if not enough data has been received yet. * * @param delimiter The delimiter @@ -973,16 +973,16 @@ * stream has been reached. */ - (nullable OFString *)tryReadTillDelimiter: (OFString *)delimiter encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Writes everything in the write buffer to the stream. */ - (void)flushWriteBuffer; -/*! +/** * @brief Writes from a buffer into the stream. * * @param buffer The buffer from which the data is written into the stream * @param length The length of the data that should be written * @return The number of bytes written. This can only differ from the specified @@ -990,21 +990,21 @@ */ - (size_t)writeBuffer: (const void *)buffer length: (size_t)length; #ifdef OF_HAVE_SOCKETS -/*! +/** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param data The data which is written into the stream */ - (void)asyncWriteData: (OFData *)data; -/*! +/** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * @@ -1012,21 +1012,21 @@ * @param runLoopMode The run loop mode in which to perform the async write */ - (void)asyncWriteData: (OFData *)data runLoopMode: (of_run_loop_mode_t)runLoopMode; -/*! +/** * @brief Asynchronously writes a string in UTF-8 encoding into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param string The string which is written into the stream */ - (void)asyncWriteString: (OFString *)string; -/*! +/** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! @@ -1036,11 +1036,11 @@ * stream */ - (void)asyncWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! @@ -1053,11 +1053,11 @@ - (void)asyncWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding runLoopMode: (of_run_loop_mode_t)runLoopMode; # ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * @@ -1067,11 +1067,11 @@ * nil if it should not repeat. */ - (void)asyncWriteData: (OFData *)data block: (of_stream_async_write_data_block_t)block; -/*! +/** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * @@ -1083,11 +1083,11 @@ */ - (void)asyncWriteData: (OFData *)data runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_async_write_data_block_t)block; -/*! +/** * @brief Asynchronously writes a string into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * @@ -1097,11 +1097,11 @@ * nil if it should not repeat. */ - (void)asyncWriteString: (OFString *)string block: (of_stream_async_write_string_block_t)block; -/*! +/** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! @@ -1115,11 +1115,11 @@ */ - (void)asyncWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding block: (of_stream_async_write_string_block_t)block; -/*! +/** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! @@ -1137,53 +1137,53 @@ runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_async_write_string_block_t)block; # endif #endif -/*! +/** * @brief Writes a uint8_t into the stream. * * @param int8 A uint8_t */ - (void)writeInt8: (uint8_t)int8; -/*! +/** * @brief Writes a uint16_t into the stream, encoded in big endian. * * @param int16 A uint16_t */ - (void)writeBigEndianInt16: (uint16_t)int16; -/*! +/** * @brief Writes a uint32_t into the stream, encoded in big endian. * * @param int32 A uint32_t */ - (void)writeBigEndianInt32: (uint32_t)int32; -/*! +/** * @brief Writes a uint64_t into the stream, encoded in big endian. * * @param int64 A uint64_t */ - (void)writeBigEndianInt64: (uint64_t)int64; -/*! +/** * @brief Writes a float into the stream, encoded in big endian. * * @param float_ A float */ - (void)writeBigEndianFloat: (float)float_; -/*! +/** * @brief Writes a double into the stream, encoded in big endian. * * @param double_ A double */ - (void)writeBigEndianDouble: (double)double_; -/*! +/** * @brief Writes the specified number of uint16_ts into the stream, encoded in * big endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1191,11 +1191,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeBigEndianInt16s: (const uint16_t *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of uint32_ts into the stream, encoded in * big endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1203,11 +1203,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeBigEndianInt32s: (const uint32_t *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of uint64_ts into the stream, encoded in * big endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1215,11 +1215,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeBigEndianInt64s: (const uint64_t *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of floats into the stream, encoded in big * endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1227,11 +1227,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeBigEndianFloats: (const float *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of doubles into the stream, encoded in * big endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1239,46 +1239,46 @@ * @return The number of bytes written to the stream */ - (size_t)writeBigEndianDoubles: (const double *)buffer count: (size_t)count; -/*! +/** * @brief Writes a uint16_t into the stream, encoded in little endian. * * @param int16 A uint16_t */ - (void)writeLittleEndianInt16: (uint16_t)int16; -/*! +/** * @brief Writes a uint32_t into the stream, encoded in little endian. * * @param int32 A uint32_t */ - (void)writeLittleEndianInt32: (uint32_t)int32; -/*! +/** * @brief Writes a uint64_t into the stream, encoded in little endian. * * @param int64 A uint64_t */ - (void)writeLittleEndianInt64: (uint64_t)int64; -/*! +/** * @brief Writes a float into the stream, encoded in little endian. * * @param float_ A float */ - (void)writeLittleEndianFloat: (float)float_; -/*! +/** * @brief Writes a double into the stream, encoded in little endian. * * @param double_ A double */ - (void)writeLittleEndianDouble: (double)double_; -/*! +/** * @brief Writes the specified number of uint16_ts into the stream, encoded in * little endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1286,11 +1286,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeLittleEndianInt16s: (const uint16_t *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of uint32_ts into the stream, encoded in * little endian. * * @param count The number of uint32_ts to write * @param buffer The buffer from which the data is written to the stream after @@ -1298,11 +1298,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeLittleEndianInt32s: (const uint32_t *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of uint64_ts into the stream, encoded in * little endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1310,11 +1310,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeLittleEndianInt64s: (const uint64_t *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of floats into the stream, encoded in * little endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1322,11 +1322,11 @@ * @return The number of bytes written to the stream */ - (size_t)writeLittleEndianFloats: (const float *)buffer count: (size_t)count; -/*! +/** * @brief Writes the specified number of doubles into the stream, encoded in * little endian. * * @param buffer The buffer from which the data is written to the stream after * it has been byte swapped if necessary @@ -1334,27 +1334,27 @@ * @return The number of bytes written to the stream */ - (size_t)writeLittleEndianDoubles: (const double *)buffer count: (size_t)count; -/*! +/** * @brief Writes OFData into the stream. * * @param data The OFData to write into the stream * @return The number of bytes written */ - (size_t)writeData: (OFData *)data; -/*! +/** * @brief Writes a string into the stream, without the trailing zero. * * @param string The string from which the data is written to the stream * @return The number of bytes written */ - (size_t)writeString: (OFString *)string; -/*! +/** * @brief Writes a string into the stream in the specified encoding, without * the trailing zero. * * @param string The string from which the data is written to the stream * @param encoding The encoding in which to write the string to the stream @@ -1361,19 +1361,19 @@ * @return The number of bytes written */ - (size_t)writeString: (OFString *)string encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Writes a string into the stream with a trailing newline. * * @param string The string from which the data is written to the stream * @return The number of bytes written */ - (size_t)writeLine: (OFString *)string; -/*! +/** * @brief Writes a string into the stream in the specified encoding with a * trailing newline. * * @param string The string from which the data is written to the stream * @param encoding The encoding in which to write the string to the stream @@ -1380,11 +1380,11 @@ * @return The number of bytes written */ - (size_t)writeLine: (OFString *)string encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Writes a formatted string into the stream. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -1392,11 +1392,11 @@ * @param format A string used as format * @return The number of bytes written */ - (size_t)writeFormat: (OFConstantString *)format, ...; -/*! +/** * @brief Writes a formatted string into the stream. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -1407,17 +1407,17 @@ */ - (size_t)writeFormat: (OFConstantString *)format arguments: (va_list)arguments; #ifdef OF_HAVE_SOCKETS -/*! +/** * @brief Cancels all pending asynchronous requests on the stream. */ - (void)cancelAsyncRequests; #endif -/*! +/** * @brief "Reverses" a read operation, meaning the bytes from the specified * buffer will be returned on the next read operation. * * This is useful for reading into a buffer, parsing the data and then giving * back the data which does not need to be processed. This can be used to @@ -1437,18 +1437,18 @@ * @param length The length of the buffer to unread */ - (void)unreadFromBuffer: (const void *)buffer length: (size_t)length; -/*! +/** * @brief Closes the stream. * * @note If you override this, make sure to call `[super close]`! */ - (void)close; -/*! +/** * @brief Performs a lowlevel read. * * @warning Do not call this directly! * * @note Override this method with your actual read implementation when @@ -1459,11 +1459,11 @@ * @return The number of bytes read */ - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length; -/*! +/** * @brief Performs a lowlevel write. * * @warning Do not call this directly! * * @note Override this method with your actual write implementation when @@ -1474,11 +1474,11 @@ * @return The number of bytes written */ - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length; -/*! +/** * @brief Returns whether the lowlevel is at the end of the stream. * * @warning Do not call this directly! * * @note Override this method with your actual end of stream checking Index: src/OFStreamSocket.h ================================================================== --- src/OFStreamSocket.h +++ src/OFStreamSocket.h @@ -19,16 +19,16 @@ #import "socket.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFStreamSocket; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when the socket accepted a connection. * * @param acceptedSocket The socket which has been accepted * @param exception An exception which occurred while accepting the socket or * `nil` on success @@ -37,18 +37,18 @@ */ typedef bool (^of_stream_socket_async_accept_block_t)( OFStreamSocket *acceptedSocket, id _Nullable exception); #endif -/*! +/** * @protocol OFStreamSocketDelegate OFStreamSocket.h ObjFW/OFStreamSocket.h * * A delegate for OFStreamSocket. */ @protocol OFStreamSocketDelegate @optional -/*! +/** * @brief A method which is called when a socket accepted a connection. * * @param socket The socket which accepted the connection * @param acceptedSocket The socket which has been accepted * @param exception An exception that occurred while accepting, or nil on @@ -58,11 +58,11 @@ - (bool)socket: (OFStreamSocket *)socket didAcceptSocket: (OFStreamSocket *)acceptedSocket exception: (nullable id)exception; @end -/*! +/** * @class OFStreamSocket OFStreamSocket.h ObjFW/OFStreamSocket.h * * @brief A class which provides methods to create and use stream sockets. */ @interface OFStreamSocket: OFStream { of_socket_t _socket; bool _atEndOfStream, _listening; of_socket_address_t _remoteAddress; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFStreamSocket, 4) } -/*! +/** * @brief Whether the socket is a listening socket. */ @property (readonly, nonatomic, getter=isListening) bool listening; -/*! +/** * @brief The remote address. * * @note This only works for accepted sockets! */ @property (readonly, nonatomic) const of_socket_address_t *remoteAddress; -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Returns a new, autoreleased OFStreamSocket. * * @return A new, autoreleased OFStreamSocket */ + (instancetype)socket; -/*! +/** * @brief Listen on the socket. * * @param backlog Maximum length for the queue of pending connections. */ - (void)listenWithBacklog: (int)backlog; -/*! +/** * @brief Listen on the socket. */ - (void)listen; -/*! +/** * @brief Accept an incoming connection. * * @return An autoreleased OFStreamSocket for the accepted connection. */ - (instancetype)accept; -/*! +/** * @brief Asynchronously accept an incoming connection. */ - (void)asyncAccept; -/*! +/** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept */ - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously accept an incoming connection. * * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted * by the specified block as well. */ - (void)asyncAcceptWithBlock: (of_stream_socket_async_accept_block_t)block; -/*! +/** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted Index: src/OFString+CryptoHashing.h ================================================================== --- src/OFString+CryptoHashing.h +++ src/OFString+CryptoHashing.h @@ -26,42 +26,42 @@ #ifdef __cplusplus } #endif @interface OFString (CryptoHashing) -/*! +/** * @brief The MD5 hash of the string as a string. */ @property (readonly, nonatomic) OFString *MD5Hash; -/*! +/** * @brief The RIPEMD-160 hash of the string as a string. */ @property (readonly, nonatomic) OFString *RIPEMD160Hash; -/*! +/** * @brief The SHA-1 hash of the string as a string. */ @property (readonly, nonatomic) OFString *SHA1Hash; -/*! +/** * @brief The SHA-224 hash of the string as a string. */ @property (readonly, nonatomic) OFString *SHA224Hash; -/*! +/** * @brief The SHA-256 hash of the string as a string. */ @property (readonly, nonatomic) OFString *SHA256Hash; -/*! +/** * @brief The SHA-384 hash of the string as a string. */ @property (readonly, nonatomic) OFString *SHA384Hash; -/*! +/** * @brief The SHA-512 hash of the string as a string. */ @property (readonly, nonatomic) OFString *SHA512Hash; @end OF_ASSUME_NONNULL_END ADDED src/OFString+JSONParsing.h Index: src/OFString+JSONParsing.h ================================================================== --- src/OFString+JSONParsing.h +++ src/OFString+JSONParsing.h @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#import "OFString.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFString_JSONParsing_reference; +#ifdef __cplusplus +} +#endif + +@interface OFString (JSONParsing) +/** + * @brief The string interpreted as JSON and parsed as an object. + * + * @note This also allows parsing JSON5, an extension of JSON. See + * http://json5.org/ for more details. + * + * @warning Although not specified by the JSON specification, this can also + * return primitives like strings and numbers. The rationale behind + * this is that most JSON parsers allow JSON data just consisting of a + * single primitive, leading to real world JSON files sometimes only + * consisting of a single primitive. Therefore, you should not make any + * assumptions about the object returned by this method if you don't + * want your program to terminate due to a message not understood, but + * instead check the returned object using @ref isKindOfClass:. + */ +@property (readonly, nonatomic) id objectByParsingJSON; + +/** + * @brief Creates an object from the JSON value of the string. + * + * @note This also allows parsing JSON5, an extension of JSON. See + * http://json5.org/ for more details. + * + * @warning Although not specified by the JSON specification, this can also + * return primitives like strings and numbers. The rationale behind + * this is that most JSON parsers allow JSON data just consisting of a + * single primitive, leading to real world JSON files sometimes only + * consisting of a single primitive. Therefore, you should not make any + * assumptions about the object returned by this method if you don't + * want your program to terminate due to a message not understood, but + * instead check the returned object using @ref isKindOfClass:. + * + * @param depthLimit The maximum depth the parser should accept (defaults to 32 + * if not specified, 0 means no limit (insecure!)) + * + * @return An object + */ +- (id)objectByParsingJSONWithDepthLimit: (size_t)depthLimit; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFString+JSONParsing.m Index: src/OFString+JSONParsing.m ================================================================== --- src/OFString+JSONParsing.m +++ src/OFString+JSONParsing.m @@ -0,0 +1,675 @@ +/* + * 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" + +#include +#include + +#include + +#include + +#import "OFString+JSONParsing.h" +#import "OFArray.h" +#import "OFDictionary.h" +#import "OFNumber.h" +#import "OFNull.h" + +#import "OFInvalidJSONException.h" + +int _OFString_JSONParsing_reference; + +static id nextObject(const char **pointer, const char *stop, size_t *line, + size_t depthLimit); + +static void +skipWhitespaces(const char **pointer, const char *stop, size_t *line) +{ + while (*pointer < stop && (**pointer == ' ' || **pointer == '\t' || + **pointer == '\r' || **pointer == '\n')) { + if (**pointer == '\n') + (*line)++; + + (*pointer)++; + } +} + +static void +skipComment(const char **pointer, const char *stop, size_t *line) +{ + if (**pointer != '/') + return; + + if (*pointer + 1 >= stop) + return; + + (*pointer)++; + + if (**pointer == '*') { + bool lastIsAsterisk = false; + + (*pointer)++; + + while (*pointer < stop) { + if (lastIsAsterisk && **pointer == '/') { + (*pointer)++; + return; + } + + lastIsAsterisk = (**pointer == '*'); + + if (**pointer == '\n') + (*line)++; + + (*pointer)++; + } + } else if (**pointer == '/') { + (*pointer)++; + + while (*pointer < stop) { + if (**pointer == '\r' || **pointer == '\n') { + (*pointer)++; + (*line)++; + return; + } + + (*pointer)++; + } + } else + (*pointer)--; +} + +static void +skipWhitespacesAndComments(const char **pointer, const char *stop, size_t *line) +{ + const char *old = NULL; + + while (old != *pointer) { + old = *pointer; + + skipWhitespaces(pointer, stop, line); + skipComment(pointer, stop, line); + } +} + +static inline of_char16_t +parseUnicodeEscape(const char *pointer, const char *stop) +{ + of_char16_t ret = 0; + + if (pointer + 5 >= stop) + return 0xFFFF; + + if (pointer[0] != '\\' || pointer[1] != 'u') + return 0xFFFF; + + for (uint8_t i = 0; i < 4; i++) { + char c = pointer[i + 2]; + ret <<= 4; + + if (c >= '0' && c <= '9') + ret |= c - '0'; + else if (c >= 'a' && c <= 'f') + ret |= c + 10 - 'a'; + else if (c >= 'A' && c <= 'F') + ret |= c + 10 - 'A'; + else + return 0xFFFF; + } + + if (ret == 0) + return 0xFFFF; + + return ret; +} + +static inline OFString * +parseString(const char **pointer, const char *stop, size_t *line) +{ + char *buffer; + size_t i = 0; + char delimiter = **pointer; + + if (++(*pointer) + 1 >= stop) + return nil; + + if ((buffer = malloc(stop - *pointer)) == NULL) + return nil; + + while (*pointer < stop) { + /* Parse escape codes */ + if (**pointer == '\\') { + if (++(*pointer) >= stop) { + free(buffer); + return nil; + } + + switch (**pointer) { + case '"': + case '\\': + case '/': + buffer[i++] = **pointer; + (*pointer)++; + break; + case 'b': + buffer[i++] = '\b'; + (*pointer)++; + break; + case 'f': + buffer[i++] = '\f'; + (*pointer)++; + break; + case 'n': + buffer[i++] = '\n'; + (*pointer)++; + break; + case 'r': + buffer[i++] = '\r'; + (*pointer)++; + break; + case 't': + buffer[i++] = '\t'; + (*pointer)++; + break; + /* Parse Unicode escape sequence */ + case 'u':; + of_char16_t c1, c2; + of_unichar_t c; + size_t l; + + c1 = parseUnicodeEscape(*pointer - 1, stop); + if (c1 == 0xFFFF) { + free(buffer); + return nil; + } + + /* Low surrogate */ + if ((c1 & 0xFC00) == 0xDC00) { + free(buffer); + return nil; + } + + /* Normal character */ + if ((c1 & 0xFC00) != 0xD800) { + l = of_string_utf8_encode(c1, + buffer + i); + if (l == 0) { + free(buffer); + return nil; + } + + i += l; + *pointer += 5; + + break; + } + + /* + * If we are still here, we only got one UTF-16 + * surrogate and now need to get the other one + * in order to produce UTF-8 and not CESU-8. + */ + c2 = parseUnicodeEscape(*pointer + 5, stop); + if (c2 == 0xFFFF) { + free(buffer); + return nil; + } + + c = (((c1 & 0x3FF) << 10) | + (c2 & 0x3FF)) + 0x10000; + + l = of_string_utf8_encode(c, buffer + i); + if (l == 0) { + free(buffer); + return nil; + } + + i += l; + *pointer += 11; + + break; + case '\r': + (*pointer)++; + + if (*pointer < stop && **pointer == '\n') { + (*pointer)++; + (*line)++; + } + + break; + case '\n': + (*pointer)++; + (*line)++; + break; + default: + free(buffer); + return nil; + } + /* End of string found */ + } else if (**pointer == delimiter) { + OFString *ret; + + @try { + ret = [OFString stringWithUTF8String: buffer + length: i]; + } @finally { + free(buffer); + } + + (*pointer)++; + + return ret; + /* Newlines in strings are disallowed */ + } else if (**pointer == '\n' || **pointer == '\r') { + (*line)++; + free(buffer); + return nil; + } else { + buffer[i++] = **pointer; + (*pointer)++; + } + } + + free(buffer); + return nil; +} + +static inline OFString * +parseIdentifier(const char **pointer, const char *stop) +{ + char *buffer; + size_t i = 0; + + if ((buffer = malloc(stop - *pointer)) == NULL) + return nil; + + while (*pointer < stop) { + if ((**pointer >= 'a' && **pointer <= 'z') || + (**pointer >= 'A' && **pointer <= 'Z') || + (**pointer >= '0' && **pointer <= '9') || + **pointer == '_' || **pointer == '$' || + (**pointer & 0x80)) { + buffer[i++] = **pointer; + (*pointer)++; + } else if (**pointer == '\\') { + of_char16_t c1, c2; + of_unichar_t c; + size_t l; + + if (++(*pointer) >= stop || **pointer != 'u') { + free(buffer); + return nil; + } + + c1 = parseUnicodeEscape(*pointer - 1, stop); + if (c1 == 0xFFFF) { + free(buffer); + return nil; + } + + /* Low surrogate */ + if ((c1 & 0xFC00) == 0xDC00) { + free(buffer); + return nil; + } + + /* Normal character */ + if ((c1 & 0xFC00) != 0xD800) { + l = of_string_utf8_encode(c1, buffer + i); + if (l == 0) { + free(buffer); + return nil; + } + + i += l; + *pointer += 5; + + continue; + } + + /* + * If we are still here, we only got one UTF-16 + * surrogate and now need to get the other one in order + * to produce UTF-8 and not CESU-8. + */ + c2 = parseUnicodeEscape(*pointer + 5, stop); + if (c2 == 0xFFFF) { + free(buffer); + return nil; + } + + c = (((c1 & 0x3FF) << 10) | (c2 & 0x3FF)) + 0x10000; + + l = of_string_utf8_encode(c, buffer + i); + if (l == 0) { + free(buffer); + return nil; + } + + i += l; + *pointer += 11; + } else { + OFString *ret; + + if (i == 0 || (buffer[0] >= '0' && buffer[0] <= '9')) { + free(buffer); + return nil; + } + + @try { + ret = [OFString stringWithUTF8String: buffer + length: i]; + } @finally { + free(buffer); + } + + return ret; + } + } + + /* + * It is never possible to end with an identifier, thus we should never + * reach stop. + */ + return nil; +} + +static inline OFMutableArray * +parseArray(const char **pointer, const char *stop, size_t *line, + size_t depthLimit) +{ + OFMutableArray *array = [OFMutableArray array]; + + if (++(*pointer) >= stop) + return nil; + + if (--depthLimit == 0) + return nil; + + while (**pointer != ']') { + id object; + + skipWhitespacesAndComments(pointer, stop, line); + if (*pointer >= stop) + return nil; + + if (**pointer == ']') + break; + + if (**pointer == ',') { + (*pointer)++; + skipWhitespacesAndComments(pointer, stop, line); + + if (*pointer >= stop || **pointer != ']') + return nil; + + break; + } + + object = nextObject(pointer, stop, line, depthLimit); + if (object == nil) + return nil; + + [array addObject: object]; + + skipWhitespacesAndComments(pointer, stop, line); + if (*pointer >= stop) + return nil; + + if (**pointer == ',') { + (*pointer)++; + skipWhitespacesAndComments(pointer, stop, line); + + if (*pointer >= stop) + return nil; + } else if (**pointer != ']') + return nil; + } + + (*pointer)++; + + return array; +} + +static inline OFMutableDictionary * +parseDictionary(const char **pointer, const char *stop, size_t *line, + size_t depthLimit) +{ + OFMutableDictionary *dictionary = [OFMutableDictionary dictionary]; + + if (++(*pointer) >= stop) + return nil; + + if (--depthLimit == 0) + return nil; + + while (**pointer != '}') { + OFString *key; + id object; + + skipWhitespacesAndComments(pointer, stop, line); + if (*pointer >= stop) + return nil; + + if (**pointer == '}') + break; + + if (**pointer == ',') { + (*pointer)++; + skipWhitespacesAndComments(pointer, stop, line); + + if (*pointer >= stop || **pointer != '}') + return nil; + + break; + } + + skipWhitespacesAndComments(pointer, stop, line); + if (*pointer + 1 >= stop) + return nil; + + if ((**pointer >= 'a' && **pointer <= 'z') || + (**pointer >= 'A' && **pointer <= 'Z') || + **pointer == '_' || **pointer == '$' || **pointer == '\\') + key = parseIdentifier(pointer, stop); + else + key = nextObject(pointer, stop, line, depthLimit); + + if (![key isKindOfClass: [OFString class]]) + return nil; + + skipWhitespacesAndComments(pointer, stop, line); + if (*pointer + 1 >= stop || **pointer != ':') + return nil; + + (*pointer)++; + + object = nextObject(pointer, stop, line, depthLimit); + if (object == nil) + return nil; + + [dictionary setObject: object + forKey: key]; + + skipWhitespacesAndComments(pointer, stop, line); + if (*pointer >= stop) + return nil; + + if (**pointer == ',') { + (*pointer)++; + skipWhitespacesAndComments(pointer, stop, line); + + if (*pointer >= stop) + return nil; + } else if (**pointer != '}') + return nil; + } + + (*pointer)++; + + return dictionary; +} + +static inline OFNumber * +parseNumber(const char **pointer, const char *stop, size_t *line) +{ + bool isNegative = (*pointer < stop && (*pointer)[0] == '-'); + bool hasDecimal = false; + size_t i; + OFString *string; + OFNumber *number; + + for (i = 0; *pointer + i < stop; i++) { + if ((*pointer)[i] == '.') + hasDecimal = true; + + if ((*pointer)[i] == ' ' || (*pointer)[i] == '\t' || + (*pointer)[i] == '\r' || (*pointer)[i] == '\n' || + (*pointer)[i] == ',' || (*pointer)[i] == ']' || + (*pointer)[i] == '}') { + if ((*pointer)[i] == '\n') + (*line)++; + + break; + } + } + + string = [[OFString alloc] initWithUTF8String: *pointer + length: i]; + *pointer += i; + + @try { + if (hasDecimal) + number = [OFNumber numberWithDouble: + string.doubleValue]; + else if ([string isEqual: @"Infinity"]) + number = [OFNumber numberWithDouble: INFINITY]; + else if ([string isEqual: @"-Infinity"]) + number = [OFNumber numberWithDouble: -INFINITY]; + else if (isNegative) + number = [OFNumber numberWithLongLong: + [string longLongValueWithBase: 0]]; + else + number = [OFNumber numberWithUnsignedLongLong: + [string unsignedLongLongValueWithBase: 0]]; + } @finally { + [string release]; + } + + return number; +} + +static id +nextObject(const char **pointer, const char *stop, size_t *line, + size_t depthLimit) +{ + skipWhitespacesAndComments(pointer, stop, line); + + if (*pointer >= stop) + return nil; + + switch (**pointer) { + case '"': + case '\'': + return parseString(pointer, stop, line); + case '[': + return parseArray(pointer, stop, line, depthLimit); + case '{': + return parseDictionary(pointer, stop, line, depthLimit); + case 't': + if (*pointer + 3 >= stop) + return nil; + + if (memcmp(*pointer, "true", 4) != 0) + return nil; + + (*pointer) += 4; + + return [OFNumber numberWithBool: true]; + case 'f': + if (*pointer + 4 >= stop) + return nil; + + if (memcmp(*pointer, "false", 5) != 0) + return nil; + + (*pointer) += 5; + + return [OFNumber numberWithBool: false]; + case 'n': + if (*pointer + 3 >= stop) + return nil; + + if (memcmp(*pointer, "null", 4) != 0) + return nil; + + (*pointer) += 4; + + return [OFNull null]; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case '.': + case 'I': + return parseNumber(pointer, stop, line); + default: + return nil; + } +} + +@implementation OFString (JSONParsing) +- (id)objectByParsingJSON +{ + return [self objectByParsingJSONWithDepthLimit: 32]; +} + +- (id)objectByParsingJSONWithDepthLimit: (size_t)depthLimit +{ + void *pool = objc_autoreleasePoolPush(); + const char *pointer = self.UTF8String; + const char *stop = pointer + self.UTF8StringLength; + id object; + size_t line = 1; + +#ifdef __clang_analyzer__ + assert(pointer != NULL); +#endif + + object = nextObject(&pointer, stop, &line, depthLimit); + skipWhitespacesAndComments(&pointer, stop, &line); + + if (pointer < stop || object == nil) + @throw [OFInvalidJSONException exceptionWithString: self + line: line]; + + [object retain]; + + objc_autoreleasePoolPop(pool); + + return [object autorelease]; +} +@end DELETED src/OFString+JSONValue.h Index: src/OFString+JSONValue.h ================================================================== --- src/OFString+JSONValue.h +++ src/OFString+JSONValue.h @@ -1,71 +0,0 @@ -/* - * 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. - */ - -#import "OFString.h" - -OF_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFString_JSONValue_reference; -#ifdef __cplusplus -} -#endif - -@interface OFString (JSONValue) -/*! - * @brief The string interpreted as JSON and parsed as an object. - * - * @note This also allows parsing JSON5, an extension of JSON. See - * http://json5.org/ for more details. - * - * @warning Although not specified by the JSON specification, this can also - * return primitives like strings and numbers. The rationale behind - * this is that most JSON parsers allow JSON data just consisting of a - * single primitive, leading to real world JSON files sometimes only - * consisting of a single primitive. Therefore, you should not make any - * assumptions about the object returned by this method if you don't - * want your program to terminate due to a message not understood, but - * instead check the returned object using @ref isKindOfClass:. - */ -@property (readonly, nonatomic) id JSONValue; - -/*! - * @brief Creates an object from the JSON value of the string. - * - * @note This also allows parsing JSON5, an extension of JSON. See - * http://json5.org/ for more details. - * - * @warning Although not specified by the JSON specification, this can also - * return primitives like strings and numbers. The rationale behind - * this is that most JSON parsers allow JSON data just consisting of a - * single primitive, leading to real world JSON files sometimes only - * consisting of a single primitive. Therefore, you should not make any - * assumptions about the object returned by this method if you don't - * want your program to terminate due to a message not understood, but - * instead check the returned object using @ref isKindOfClass:. - * - * @param depthLimit The maximum depth the parser should accept (defaults to 32 - * if not specified, 0 means no limit (insecure!)) - * - * @return An object - */ -- (id)JSONValueWithDepthLimit: (size_t)depthLimit; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFString+JSONValue.m Index: src/OFString+JSONValue.m ================================================================== --- src/OFString+JSONValue.m +++ src/OFString+JSONValue.m @@ -1,675 +0,0 @@ -/* - * 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" - -#include -#include - -#include - -#include - -#import "OFString+JSONValue.h" -#import "OFArray.h" -#import "OFDictionary.h" -#import "OFNumber.h" -#import "OFNull.h" - -#import "OFInvalidJSONException.h" - -int _OFString_JSONValue_reference; - -static id nextObject(const char **pointer, const char *stop, size_t *line, - size_t depthLimit); - -static void -skipWhitespaces(const char **pointer, const char *stop, size_t *line) -{ - while (*pointer < stop && (**pointer == ' ' || **pointer == '\t' || - **pointer == '\r' || **pointer == '\n')) { - if (**pointer == '\n') - (*line)++; - - (*pointer)++; - } -} - -static void -skipComment(const char **pointer, const char *stop, size_t *line) -{ - if (**pointer != '/') - return; - - if (*pointer + 1 >= stop) - return; - - (*pointer)++; - - if (**pointer == '*') { - bool lastIsAsterisk = false; - - (*pointer)++; - - while (*pointer < stop) { - if (lastIsAsterisk && **pointer == '/') { - (*pointer)++; - return; - } - - lastIsAsterisk = (**pointer == '*'); - - if (**pointer == '\n') - (*line)++; - - (*pointer)++; - } - } else if (**pointer == '/') { - (*pointer)++; - - while (*pointer < stop) { - if (**pointer == '\r' || **pointer == '\n') { - (*pointer)++; - (*line)++; - return; - } - - (*pointer)++; - } - } else - (*pointer)--; -} - -static void -skipWhitespacesAndComments(const char **pointer, const char *stop, size_t *line) -{ - const char *old = NULL; - - while (old != *pointer) { - old = *pointer; - - skipWhitespaces(pointer, stop, line); - skipComment(pointer, stop, line); - } -} - -static inline of_char16_t -parseUnicodeEscape(const char *pointer, const char *stop) -{ - of_char16_t ret = 0; - - if (pointer + 5 >= stop) - return 0xFFFF; - - if (pointer[0] != '\\' || pointer[1] != 'u') - return 0xFFFF; - - for (uint8_t i = 0; i < 4; i++) { - char c = pointer[i + 2]; - ret <<= 4; - - if (c >= '0' && c <= '9') - ret |= c - '0'; - else if (c >= 'a' && c <= 'f') - ret |= c + 10 - 'a'; - else if (c >= 'A' && c <= 'F') - ret |= c + 10 - 'A'; - else - return 0xFFFF; - } - - if (ret == 0) - return 0xFFFF; - - return ret; -} - -static inline OFString * -parseString(const char **pointer, const char *stop, size_t *line) -{ - char *buffer; - size_t i = 0; - char delimiter = **pointer; - - if (++(*pointer) + 1 >= stop) - return nil; - - if ((buffer = malloc(stop - *pointer)) == NULL) - return nil; - - while (*pointer < stop) { - /* Parse escape codes */ - if (**pointer == '\\') { - if (++(*pointer) >= stop) { - free(buffer); - return nil; - } - - switch (**pointer) { - case '"': - case '\\': - case '/': - buffer[i++] = **pointer; - (*pointer)++; - break; - case 'b': - buffer[i++] = '\b'; - (*pointer)++; - break; - case 'f': - buffer[i++] = '\f'; - (*pointer)++; - break; - case 'n': - buffer[i++] = '\n'; - (*pointer)++; - break; - case 'r': - buffer[i++] = '\r'; - (*pointer)++; - break; - case 't': - buffer[i++] = '\t'; - (*pointer)++; - break; - /* Parse Unicode escape sequence */ - case 'u':; - of_char16_t c1, c2; - of_unichar_t c; - size_t l; - - c1 = parseUnicodeEscape(*pointer - 1, stop); - if (c1 == 0xFFFF) { - free(buffer); - return nil; - } - - /* Low surrogate */ - if ((c1 & 0xFC00) == 0xDC00) { - free(buffer); - return nil; - } - - /* Normal character */ - if ((c1 & 0xFC00) != 0xD800) { - l = of_string_utf8_encode(c1, - buffer + i); - if (l == 0) { - free(buffer); - return nil; - } - - i += l; - *pointer += 5; - - break; - } - - /* - * If we are still here, we only got one UTF-16 - * surrogate and now need to get the other one - * in order to produce UTF-8 and not CESU-8. - */ - c2 = parseUnicodeEscape(*pointer + 5, stop); - if (c2 == 0xFFFF) { - free(buffer); - return nil; - } - - c = (((c1 & 0x3FF) << 10) | - (c2 & 0x3FF)) + 0x10000; - - l = of_string_utf8_encode(c, buffer + i); - if (l == 0) { - free(buffer); - return nil; - } - - i += l; - *pointer += 11; - - break; - case '\r': - (*pointer)++; - - if (*pointer < stop && **pointer == '\n') { - (*pointer)++; - (*line)++; - } - - break; - case '\n': - (*pointer)++; - (*line)++; - break; - default: - free(buffer); - return nil; - } - /* End of string found */ - } else if (**pointer == delimiter) { - OFString *ret; - - @try { - ret = [OFString stringWithUTF8String: buffer - length: i]; - } @finally { - free(buffer); - } - - (*pointer)++; - - return ret; - /* Newlines in strings are disallowed */ - } else if (**pointer == '\n' || **pointer == '\r') { - (*line)++; - free(buffer); - return nil; - } else { - buffer[i++] = **pointer; - (*pointer)++; - } - } - - free(buffer); - return nil; -} - -static inline OFString * -parseIdentifier(const char **pointer, const char *stop) -{ - char *buffer; - size_t i = 0; - - if ((buffer = malloc(stop - *pointer)) == NULL) - return nil; - - while (*pointer < stop) { - if ((**pointer >= 'a' && **pointer <= 'z') || - (**pointer >= 'A' && **pointer <= 'Z') || - (**pointer >= '0' && **pointer <= '9') || - **pointer == '_' || **pointer == '$' || - (**pointer & 0x80)) { - buffer[i++] = **pointer; - (*pointer)++; - } else if (**pointer == '\\') { - of_char16_t c1, c2; - of_unichar_t c; - size_t l; - - if (++(*pointer) >= stop || **pointer != 'u') { - free(buffer); - return nil; - } - - c1 = parseUnicodeEscape(*pointer - 1, stop); - if (c1 == 0xFFFF) { - free(buffer); - return nil; - } - - /* Low surrogate */ - if ((c1 & 0xFC00) == 0xDC00) { - free(buffer); - return nil; - } - - /* Normal character */ - if ((c1 & 0xFC00) != 0xD800) { - l = of_string_utf8_encode(c1, buffer + i); - if (l == 0) { - free(buffer); - return nil; - } - - i += l; - *pointer += 5; - - continue; - } - - /* - * If we are still here, we only got one UTF-16 - * surrogate and now need to get the other one in order - * to produce UTF-8 and not CESU-8. - */ - c2 = parseUnicodeEscape(*pointer + 5, stop); - if (c2 == 0xFFFF) { - free(buffer); - return nil; - } - - c = (((c1 & 0x3FF) << 10) | (c2 & 0x3FF)) + 0x10000; - - l = of_string_utf8_encode(c, buffer + i); - if (l == 0) { - free(buffer); - return nil; - } - - i += l; - *pointer += 11; - } else { - OFString *ret; - - if (i == 0 || (buffer[0] >= '0' && buffer[0] <= '9')) { - free(buffer); - return nil; - } - - @try { - ret = [OFString stringWithUTF8String: buffer - length: i]; - } @finally { - free(buffer); - } - - return ret; - } - } - - /* - * It is never possible to end with an identifier, thus we should never - * reach stop. - */ - return nil; -} - -static inline OFMutableArray * -parseArray(const char **pointer, const char *stop, size_t *line, - size_t depthLimit) -{ - OFMutableArray *array = [OFMutableArray array]; - - if (++(*pointer) >= stop) - return nil; - - if (--depthLimit == 0) - return nil; - - while (**pointer != ']') { - id object; - - skipWhitespacesAndComments(pointer, stop, line); - if (*pointer >= stop) - return nil; - - if (**pointer == ']') - break; - - if (**pointer == ',') { - (*pointer)++; - skipWhitespacesAndComments(pointer, stop, line); - - if (*pointer >= stop || **pointer != ']') - return nil; - - break; - } - - object = nextObject(pointer, stop, line, depthLimit); - if (object == nil) - return nil; - - [array addObject: object]; - - skipWhitespacesAndComments(pointer, stop, line); - if (*pointer >= stop) - return nil; - - if (**pointer == ',') { - (*pointer)++; - skipWhitespacesAndComments(pointer, stop, line); - - if (*pointer >= stop) - return nil; - } else if (**pointer != ']') - return nil; - } - - (*pointer)++; - - return array; -} - -static inline OFMutableDictionary * -parseDictionary(const char **pointer, const char *stop, size_t *line, - size_t depthLimit) -{ - OFMutableDictionary *dictionary = [OFMutableDictionary dictionary]; - - if (++(*pointer) >= stop) - return nil; - - if (--depthLimit == 0) - return nil; - - while (**pointer != '}') { - OFString *key; - id object; - - skipWhitespacesAndComments(pointer, stop, line); - if (*pointer >= stop) - return nil; - - if (**pointer == '}') - break; - - if (**pointer == ',') { - (*pointer)++; - skipWhitespacesAndComments(pointer, stop, line); - - if (*pointer >= stop || **pointer != '}') - return nil; - - break; - } - - skipWhitespacesAndComments(pointer, stop, line); - if (*pointer + 1 >= stop) - return nil; - - if ((**pointer >= 'a' && **pointer <= 'z') || - (**pointer >= 'A' && **pointer <= 'Z') || - **pointer == '_' || **pointer == '$' || **pointer == '\\') - key = parseIdentifier(pointer, stop); - else - key = nextObject(pointer, stop, line, depthLimit); - - if (![key isKindOfClass: [OFString class]]) - return nil; - - skipWhitespacesAndComments(pointer, stop, line); - if (*pointer + 1 >= stop || **pointer != ':') - return nil; - - (*pointer)++; - - object = nextObject(pointer, stop, line, depthLimit); - if (object == nil) - return nil; - - [dictionary setObject: object - forKey: key]; - - skipWhitespacesAndComments(pointer, stop, line); - if (*pointer >= stop) - return nil; - - if (**pointer == ',') { - (*pointer)++; - skipWhitespacesAndComments(pointer, stop, line); - - if (*pointer >= stop) - return nil; - } else if (**pointer != '}') - return nil; - } - - (*pointer)++; - - return dictionary; -} - -static inline OFNumber * -parseNumber(const char **pointer, const char *stop, size_t *line) -{ - bool isHex = (*pointer + 1 < stop && (*pointer)[1] == 'x'); - bool hasDecimal = false; - size_t i; - OFString *string; - OFNumber *number; - - for (i = 0; *pointer + i < stop; i++) { - if ((*pointer)[i] == '.') - hasDecimal = true; - - if ((*pointer)[i] == ' ' || (*pointer)[i] == '\t' || - (*pointer)[i] == '\r' || (*pointer)[i] == '\n' || - (*pointer)[i] == ',' || (*pointer)[i] == ']' || - (*pointer)[i] == '}') { - if ((*pointer)[i] == '\n') - (*line)++; - - break; - } - } - - string = [[OFString alloc] initWithUTF8String: *pointer - length: i]; - *pointer += i; - - @try { - if (hasDecimal) - number = [OFNumber numberWithDouble: - string.doubleValue]; - else if (isHex) - number = [OFNumber numberWithIntMax: - string.hexadecimalValue]; - else if ([string isEqual: @"Infinity"]) - number = [OFNumber numberWithDouble: INFINITY]; - else if ([string isEqual: @"-Infinity"]) - number = [OFNumber numberWithDouble: -INFINITY]; - else - number = [OFNumber numberWithIntMax: - string.decimalValue]; - } @finally { - [string release]; - } - - return number; -} - -static id -nextObject(const char **pointer, const char *stop, size_t *line, - size_t depthLimit) -{ - skipWhitespacesAndComments(pointer, stop, line); - - if (*pointer >= stop) - return nil; - - switch (**pointer) { - case '"': - case '\'': - return parseString(pointer, stop, line); - case '[': - return parseArray(pointer, stop, line, depthLimit); - case '{': - return parseDictionary(pointer, stop, line, depthLimit); - case 't': - if (*pointer + 3 >= stop) - return nil; - - if (memcmp(*pointer, "true", 4) != 0) - return nil; - - (*pointer) += 4; - - return [OFNumber numberWithBool: true]; - case 'f': - if (*pointer + 4 >= stop) - return nil; - - if (memcmp(*pointer, "false", 5) != 0) - return nil; - - (*pointer) += 5; - - return [OFNumber numberWithBool: false]; - case 'n': - if (*pointer + 3 >= stop) - return nil; - - if (memcmp(*pointer, "null", 4) != 0) - return nil; - - (*pointer) += 4; - - return [OFNull null]; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '+': - case '-': - case '.': - case 'I': - return parseNumber(pointer, stop, line); - default: - return nil; - } -} - -@implementation OFString (JSONValue) -- (id)JSONValue -{ - return [self JSONValueWithDepthLimit: 32]; -} - -- (id)JSONValueWithDepthLimit: (size_t)depthLimit -{ - void *pool = objc_autoreleasePoolPush(); - const char *pointer = self.UTF8String; - const char *stop = pointer + self.UTF8StringLength; - id object; - size_t line = 1; - -#ifdef __clang_analyzer__ - assert(pointer != NULL); -#endif - - object = nextObject(&pointer, stop, &line, depthLimit); - skipWhitespacesAndComments(&pointer, stop, &line); - - if (pointer < stop || object == nil) - @throw [OFInvalidJSONException exceptionWithString: self - line: line]; - - [object retain]; - - objc_autoreleasePoolPop(pool); - - return [object autorelease]; -} -@end Index: src/OFString+PathAdditions.h ================================================================== --- src/OFString+PathAdditions.h +++ src/OFString+PathAdditions.h @@ -32,54 +32,54 @@ #ifdef __cplusplus } #endif @interface OFString (PathAdditions) -/*! +/** * @brief Whether the path is an absolute path. */ @property (readonly, nonatomic, getter=isAbsolutePath) bool absolutePath; -/*! +/** * @brief The components of the string when interpreted as a path. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *pathComponents; -/*! +/** * @brief The last path component of the string when interpreted as a path. */ @property (readonly, nonatomic) OFString *lastPathComponent; -/*! +/** * @brief The file extension of string when interpreted as a path. */ @property (readonly, nonatomic) OFString *pathExtension; -/*! +/** * @brief The directory name of the string when interpreted as a path. */ @property (readonly, nonatomic) OFString *stringByDeletingLastPathComponent; -/*! +/** * @brief The string with the file extension of the path removed. */ @property (readonly, nonatomic) OFString *stringByDeletingPathExtension; -/*! +/** * @brief The string interpreted as a path with relative sub paths resolved. */ @property (readonly, nonatomic) OFString *stringByStandardizingPath; -/*! +/** * @brief Creates a path from the specified path components. * * @param components An array of components for the path * @return A new autoreleased OFString */ + (OFString *)pathWithComponents: (OFArray OF_GENERIC(OFString *) *)components; -/*! +/** * @brief Creates a new string by appending a path component. * * @param component The path component to append * @return A new, autoreleased OFString with the path component appended */ ADDED src/OFString+PropertyListParsing.h Index: src/OFString+PropertyListParsing.h ================================================================== --- src/OFString+PropertyListParsing.h +++ src/OFString+PropertyListParsing.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#import "OFString.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFString_PropertyListParsing_reference; +#ifdef __cplusplus +} +#endif + +@interface OFString (PropertyListParsing) +/** + * @brief The string interpreted as a property list and parsed as an object. + * + * @note This only supports XML property lists! + */ +@property (readonly, nonatomic) id objectByParsingPropertyList; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFString+PropertyListParsing.m Index: src/OFString+PropertyListParsing.m ================================================================== --- src/OFString+PropertyListParsing.m +++ src/OFString+PropertyListParsing.m @@ -0,0 +1,212 @@ +/* + * 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 "OFString+PropertyListParsing.h" +#import "OFArray.h" +#import "OFData.h" +#import "OFDate.h" +#import "OFDictionary.h" +#import "OFNumber.h" +#import "OFXMLAttribute.h" +#import "OFXMLElement.h" + +#import "OFInvalidFormatException.h" +#import "OFUnsupportedVersionException.h" + +int _OFString_PropertyListParsing_reference; + +static id parseElement(OFXMLElement *element); + +static OFArray * +parseArrayElement(OFXMLElement *element) +{ + OFMutableArray *ret = [OFMutableArray array]; + void *pool = objc_autoreleasePoolPush(); + + for (OFXMLElement *child in element.elements) + [ret addObject: parseElement(child)]; + + [ret makeImmutable]; + + objc_autoreleasePoolPop(pool); + + return ret; +} + +static OFDictionary * +parseDictElement(OFXMLElement *element) +{ + OFMutableDictionary *ret = [OFMutableDictionary dictionary]; + void *pool = objc_autoreleasePoolPush(); + OFArray OF_GENERIC(OFXMLElement *) *children = element.elements; + OFEnumerator OF_GENERIC(OFXMLElement *) *enumerator; + OFXMLElement *key, *object; + + if (children.count % 2 != 0) + @throw [OFInvalidFormatException exception]; + + enumerator = [children objectEnumerator]; + while ((key = [enumerator nextObject]) && + (object = [enumerator nextObject])) { + if (key.namespace != nil || key.attributes.count != 0 || + ![key.name isEqual: @"key"]) + @throw [OFInvalidFormatException exception]; + + [ret setObject: parseElement(object) + forKey: key.stringValue]; + } + + [ret makeImmutable]; + + objc_autoreleasePoolPop(pool); + + return ret; +} + +static OFString * +parseStringElement(OFXMLElement *element) +{ + return element.stringValue; +} + +static OFData * +parseDataElement(OFXMLElement *element) +{ + return [OFData dataWithBase64EncodedString: element.stringValue]; +} + +static OFDate * +parseDateElement(OFXMLElement *element) +{ + return [OFDate dateWithDateString: element.stringValue + format: @"%Y-%m-%dT%H:%M:%SZ"]; +} + +static OFNumber * +parseTrueElement(OFXMLElement *element) +{ + if (element.children.count != 0) + @throw [OFInvalidFormatException exception]; + + return [OFNumber numberWithBool: true]; +} + +static OFNumber * +parseFalseElement(OFXMLElement *element) +{ + if (element.children.count != 0) + @throw [OFInvalidFormatException exception]; + + return [OFNumber numberWithBool: false]; +} + +static OFNumber * +parseRealElement(OFXMLElement *element) +{ + return [OFNumber numberWithDouble: element.doubleValue]; +} + +static OFNumber * +parseIntegerElement(OFXMLElement *element) +{ + void *pool = objc_autoreleasePoolPush(); + OFString *stringValue; + OFNumber *ret; + + stringValue = element.stringValue.stringByDeletingEnclosingWhitespaces; + + if ([stringValue hasPrefix: @"-"]) + ret = [OFNumber numberWithLongLong: stringValue.longLongValue]; + else + ret = [OFNumber numberWithUnsignedLongLong: + stringValue.unsignedLongLongValue]; + + [ret retain]; + + objc_autoreleasePoolPop(pool); + + return [ret autorelease]; +} + +static id +parseElement(OFXMLElement *element) +{ + OFString *elementName; + + if (element.namespace != nil || element.attributes.count != 0) + @throw [OFInvalidFormatException exception]; + + elementName = element.name; + + if ([elementName isEqual: @"array"]) + return parseArrayElement(element); + else if ([elementName isEqual: @"dict"]) + return parseDictElement(element); + else if ([elementName isEqual: @"string"]) + return parseStringElement(element); + else if ([elementName isEqual: @"data"]) + return parseDataElement(element); + else if ([elementName isEqual: @"date"]) + return parseDateElement(element); + else if ([elementName isEqual: @"true"]) + return parseTrueElement(element); + else if ([elementName isEqual: @"false"]) + return parseFalseElement(element); + else if ([elementName isEqual: @"real"]) + return parseRealElement(element); + else if ([elementName isEqual: @"integer"]) + return parseIntegerElement(element); + else + @throw [OFInvalidFormatException exception]; +} + +@implementation OFString (PropertyListParsing) +- (id)objectByParsingPropertyList +{ + void *pool = objc_autoreleasePoolPush(); + OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self]; + OFXMLAttribute *versionAttribute; + OFArray OF_GENERIC(OFXMLElement *) *elements; + id ret; + + if (![rootElement.name isEqual: @"plist"] || + rootElement.namespace != nil) + @throw [OFInvalidFormatException exception]; + + versionAttribute = [rootElement attributeForName: @"version"]; + + if (versionAttribute == nil) + @throw [OFInvalidFormatException exception]; + + if (![versionAttribute.stringValue isEqual: @"1.0"]) + @throw [OFUnsupportedVersionException + exceptionWithVersion: [versionAttribute stringValue]]; + + elements = rootElement.elements; + + if (elements.count != 1) + @throw [OFInvalidFormatException exception]; + + ret = parseElement(elements.firstObject); + + [ret retain]; + objc_autoreleasePoolPop(pool); + return [ret autorelease]; +} +@end DELETED src/OFString+PropertyListValue.h Index: src/OFString+PropertyListValue.h ================================================================== --- src/OFString+PropertyListValue.h +++ src/OFString+PropertyListValue.h @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#import "OFString.h" - -OF_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFString_PropertyListValue_reference; -#ifdef __cplusplus -} -#endif - -@interface OFString (PropertyListValue) -/*! - * @brief The string interpreted as a property list and parsed as an object. - * - * @note This only supports XML property lists! - */ -@property (readonly, nonatomic) id propertyListValue; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFString+PropertyListValue.m Index: src/OFString+PropertyListValue.m ================================================================== --- src/OFString+PropertyListValue.m +++ src/OFString+PropertyListValue.m @@ -1,196 +0,0 @@ -/* - * 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 "OFString+PropertyListValue.h" -#import "OFArray.h" -#import "OFData.h" -#import "OFDate.h" -#import "OFDictionary.h" -#import "OFNumber.h" -#import "OFXMLAttribute.h" -#import "OFXMLElement.h" - -#import "OFInvalidFormatException.h" -#import "OFUnsupportedVersionException.h" - -int _OFString_PropertyListValue_reference; - -static id parseElement(OFXMLElement *element); - -static OFArray * -parseArrayElement(OFXMLElement *element) -{ - OFMutableArray *ret = [OFMutableArray array]; - void *pool = objc_autoreleasePoolPush(); - - for (OFXMLElement *child in element.elements) - [ret addObject: parseElement(child)]; - - [ret makeImmutable]; - - objc_autoreleasePoolPop(pool); - - return ret; -} - -static OFDictionary * -parseDictElement(OFXMLElement *element) -{ - OFMutableDictionary *ret = [OFMutableDictionary dictionary]; - void *pool = objc_autoreleasePoolPush(); - OFArray OF_GENERIC(OFXMLElement *) *children = element.elements; - OFEnumerator OF_GENERIC(OFXMLElement *) *enumerator; - OFXMLElement *key, *object; - - if (children.count % 2 != 0) - @throw [OFInvalidFormatException exception]; - - enumerator = [children objectEnumerator]; - while ((key = [enumerator nextObject]) && - (object = [enumerator nextObject])) { - if (key.namespace != nil || key.attributes.count != 0 || - ![key.name isEqual: @"key"]) - @throw [OFInvalidFormatException exception]; - - [ret setObject: parseElement(object) - forKey: key.stringValue]; - } - - [ret makeImmutable]; - - objc_autoreleasePoolPop(pool); - - return ret; -} - -static OFString * -parseStringElement(OFXMLElement *element) -{ - return element.stringValue; -} - -static OFData * -parseDataElement(OFXMLElement *element) -{ - return [OFData dataWithBase64EncodedString: element.stringValue]; -} - -static OFDate * -parseDateElement(OFXMLElement *element) -{ - return [OFDate dateWithDateString: element.stringValue - format: @"%Y-%m-%dT%H:%M:%SZ"]; -} - -static OFNumber * -parseTrueElement(OFXMLElement *element) -{ - if (element.children.count != 0) - @throw [OFInvalidFormatException exception]; - - return [OFNumber numberWithBool: true]; -} - -static OFNumber * -parseFalseElement(OFXMLElement *element) -{ - if (element.children.count != 0) - @throw [OFInvalidFormatException exception]; - - return [OFNumber numberWithBool: false]; -} - -static OFNumber * -parseRealElement(OFXMLElement *element) -{ - return [OFNumber numberWithDouble: element.doubleValue]; -} - -static OFNumber * -parseIntegerElement(OFXMLElement *element) -{ - return [OFNumber numberWithIntMax: element.decimalValue]; -} - -static id -parseElement(OFXMLElement *element) -{ - OFString *elementName; - - if (element.namespace != nil || element.attributes.count != 0) - @throw [OFInvalidFormatException exception]; - - elementName = element.name; - - if ([elementName isEqual: @"array"]) - return parseArrayElement(element); - else if ([elementName isEqual: @"dict"]) - return parseDictElement(element); - else if ([elementName isEqual: @"string"]) - return parseStringElement(element); - else if ([elementName isEqual: @"data"]) - return parseDataElement(element); - else if ([elementName isEqual: @"date"]) - return parseDateElement(element); - else if ([elementName isEqual: @"true"]) - return parseTrueElement(element); - else if ([elementName isEqual: @"false"]) - return parseFalseElement(element); - else if ([elementName isEqual: @"real"]) - return parseRealElement(element); - else if ([elementName isEqual: @"integer"]) - return parseIntegerElement(element); - else - @throw [OFInvalidFormatException exception]; -} - -@implementation OFString (PropertyListValue) -- (id)propertyListValue -{ - void *pool = objc_autoreleasePoolPush(); - OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self]; - OFXMLAttribute *versionAttribute; - OFArray OF_GENERIC(OFXMLElement *) *elements; - id ret; - - if (![rootElement.name isEqual: @"plist"] || - rootElement.namespace != nil) - @throw [OFInvalidFormatException exception]; - - versionAttribute = [rootElement attributeForName: @"version"]; - - if (versionAttribute == nil) - @throw [OFInvalidFormatException exception]; - - if (![versionAttribute.stringValue isEqual: @"1.0"]) - @throw [OFUnsupportedVersionException - exceptionWithVersion: [versionAttribute stringValue]]; - - elements = rootElement.elements; - - if (elements.count != 1) - @throw [OFInvalidFormatException exception]; - - ret = parseElement(elements.firstObject); - - [ret retain]; - objc_autoreleasePoolPop(pool); - return [ret autorelease]; -} -@end Index: src/OFString+Serialization.h ================================================================== --- src/OFString+Serialization.h +++ src/OFString+Serialization.h @@ -26,12 +26,12 @@ #ifdef __cplusplus } #endif @interface OFString (Serialization) -/*! +/** * @brief The string interpreted as serialization and parsed as an object. */ @property (readonly, nonatomic) id objectByDeserializing; @end OF_ASSUME_NONNULL_END Index: src/OFString+Serialization.m ================================================================== --- src/OFString+Serialization.m +++ src/OFString+Serialization.m @@ -50,11 +50,11 @@ version = [root attributeForName: @"version"].stringValue; if (version == nil) @throw [OFInvalidArgumentException exception]; - if (version.decimalValue != 1) + if (version.unsignedLongLongValue != 1) @throw [OFUnsupportedVersionException exceptionWithVersion: version]; elements = [root elementsForNamespace: OF_SERIALIZATION_NS]; Index: src/OFString+URLEncoding.h ================================================================== --- src/OFString+URLEncoding.h +++ src/OFString+URLEncoding.h @@ -28,16 +28,16 @@ #ifdef __cplusplus } #endif @interface OFString (URLEncoding) -/*! +/** * @brief The string as an URL decoded string. */ @property (readonly, nonatomic) OFString *stringByURLDecoding; -/*! +/** * @brief Encodes a string for use in a URL, but does not escape the specified * allowed characters. * * @param allowedCharacters A character set of characters that should not be * escaped Index: src/OFString+XMLEscaping.h ================================================================== --- src/OFString+XMLEscaping.h +++ src/OFString+XMLEscaping.h @@ -26,12 +26,12 @@ #ifdef __cplusplus } #endif @interface OFString (XMLEscaping) -/*! +/** * @brief The string in a form escaped for use in an XML document. */ @property (readonly, nonatomic) OFString *stringByXMLEscaping; @end OF_ASSUME_NONNULL_END Index: src/OFString+XMLUnescaping.h ================================================================== --- src/OFString+XMLUnescaping.h +++ src/OFString+XMLUnescaping.h @@ -17,11 +17,11 @@ #import "OFString.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef __cplusplus extern "C" { #endif extern int _OFString_XMLUnescaping_reference; @@ -28,11 +28,11 @@ #ifdef __cplusplus } #endif #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called to replace unknown XML entities in an XML * string. * * @param string The XML string which contains an unknown entity * @param entity The XML entity which is unknown @@ -40,18 +40,18 @@ */ typedef OFString *_Nullable (^of_string_xml_unescaping_block_t)( OFString *string, OFString *entity); #endif -/*! +/** * @protocol OFStringXMLUnescapingDelegate OFString.h ObjFW/OFString.h * * @brief A protocol that needs to be implemented by delegates for * stringByXMLUnescapingWithHandler:. */ @protocol OFStringXMLUnescapingDelegate -/*! +/** * @brief This callback is called when an unknown entity was found while trying * to unescape XML. * * The callback is supposed to return a substitution for the entity or `nil` if * it is unknown to the callback as well, in which case an exception will be @@ -64,26 +64,26 @@ - (nullable OFString *)string: (OFString *)string containsUnknownEntityNamed: (OFString *)entity; @end @interface OFString (XMLUnescaping) -/*! +/** * @brief The string with XML entities unescapted. */ @property (readonly, nonatomic) OFString *stringByXMLUnescaping; -/*! +/** * @brief Unescapes XML in the string and uses the specified delegate for * unknown entities. * * @param delegate An OFXMLUnescapingDelegate as a handler for unknown entities */ - (OFString *)stringByXMLUnescapingWithDelegate: (nullable id )delegate; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Unescapes XML in the string and uses the specified block for unknown * entities. * * @param block A block which handles unknown entities */ Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -44,11 +44,11 @@ # import "OFMessagePackRepresentation.h" #endif OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef __OBJC__ @class OFConstantString; @class OFString; #else @@ -62,57 +62,57 @@ typedef uint_least16_t of_char16_t; typedef uint_least32_t of_char32_t; #endif typedef of_char32_t of_unichar_t; -/*! +/** * @brief The encoding of a string. */ typedef enum of_string_encoding_t { /* * UTF-8 *has* to be 0, so that if the current @ref OFLocale is * `nil`, `[OFLocale encoding]` returns UTF-8. */ - /*! UTF-8 */ + /** UTF-8 */ OF_STRING_ENCODING_UTF_8, - /*! ASCII */ + /** ASCII */ OF_STRING_ENCODING_ASCII, - /*! ISO 8859-1 */ + /** ISO 8859-1 */ OF_STRING_ENCODING_ISO_8859_1, - /*! ISO 8859-2 */ + /** ISO 8859-2 */ OF_STRING_ENCODING_ISO_8859_2, - /*! ISO 8859-3 */ + /** ISO 8859-3 */ OF_STRING_ENCODING_ISO_8859_3, - /*! ISO 8859-15 */ + /** ISO 8859-15 */ OF_STRING_ENCODING_ISO_8859_15, - /*! Windows-1251 */ + /** Windows-1251 */ OF_STRING_ENCODING_WINDOWS_1251, - /*! Windows-1252 */ + /** Windows-1252 */ OF_STRING_ENCODING_WINDOWS_1252, - /*! Codepage 437 */ + /** Codepage 437 */ OF_STRING_ENCODING_CODEPAGE_437, - /*! Codepage 850 */ + /** Codepage 850 */ OF_STRING_ENCODING_CODEPAGE_850, - /*! Codepage 858 */ + /** Codepage 858 */ OF_STRING_ENCODING_CODEPAGE_858, - /*! Mac OS Roman */ + /** Mac OS Roman */ OF_STRING_ENCODING_MAC_ROMAN, - /*! KOI8-R */ + /** KOI8-R */ OF_STRING_ENCODING_KOI8_R, - /*! KOI8-U */ + /** KOI8-U */ OF_STRING_ENCODING_KOI8_U, - /*! Try to automatically detect the encoding */ + /** Try to automatically detect the encoding */ OF_STRING_ENCODING_AUTODETECT = 0xFF } of_string_encoding_t; enum { OF_STRING_SEARCH_BACKWARDS = 1, OF_STRING_SKIP_EMPTY = 2 }; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for enumerating the lines of a string. * * @param line The current line * @param stop A pointer to a variable that can be set to true to stop the * enumeration @@ -123,197 +123,184 @@ #ifdef __OBJC__ @class OFArray OF_GENERIC(ObjectType); @class OFCharacterSet; @class OFURL; -/*! +/** * @class OFString OFString.h ObjFW/OFString.h * * @brief A class for handling strings. */ @interface OFString: OFObject -/*! +/** * @brief The length of the string in Unicode codepoints. */ @property (readonly, nonatomic) size_t length; -/*! +/** * @brief The OFString as a UTF-8 encoded C string. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const char *UTF8String OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The number of bytes the string needs in UTF-8 encoding. */ @property (readonly, nonatomic) size_t UTF8StringLength; -/*! +/** * @brief The string in uppercase. */ @property (readonly, nonatomic) OFString *uppercaseString; -/*! +/** * @brief The string in lowercase. */ @property (readonly, nonatomic) OFString *lowercaseString; -/*! +/** * @brief The string in capitalized form. * * @note This only considers spaces, tabs and newlines to be word delimiters! * Also note that this might change in the future to all word delimiters * specified by Unicode! */ @property (readonly, nonatomic) OFString *capitalizedString; -/*! - * @brief The decimal value of the string as an `intmax_t`. +/** + * @brief The decimal value of the string as a `long long`. * * Leading and trailing whitespaces are ignored. * * If the string contains any non-number characters, an * @ref OFInvalidFormatException is thrown. * - * If the number is too big to fit into an `intmax_t`, an + * If the number is too big to fit into a `long long`, an * @ref OFOutOfRangeException is thrown. */ -@property (readonly, nonatomic) intmax_t decimalValue; +@property (readonly, nonatomic) long long longLongValue; -/*! - * @brief The hexadecimal value of the string as an `uintmax_t`. +/** + * @brief The decimal value of the string as an `unsigned long long`. * * Leading and trailing whitespaces are ignored. * * If the string contains any non-number characters, an * @ref OFInvalidFormatException is thrown. * - * If the number is too big to fit into an `uintmax_t`, an - * @ref OFOutOfRangeException is thrown. - */ -@property (readonly, nonatomic) uintmax_t hexadecimalValue; - -/*! - * @brief The octal value of the string as an `uintmax_t`. - * - * Leading and trailing whitespaces are ignored. - * - * If the string contains any non-number characters, an - * @ref OFInvalidFormatException is thrown. - * - * If the number is too big to fit into an `uintmax_t`, an - * @ref OFOutOfRangeException is thrown. - */ -@property (readonly, nonatomic) uintmax_t octalValue; - -/*! + * If the number is too big to fit into an `unsigned long long`, an + * @ref OFOutOfRangeException is thrown. + */ +@property (readonly, nonatomic) unsigned long long unsignedLongLongValue; + +/** * @brief The float value of the string as a float. * * If the string contains any non-number characters, an * @ref OFInvalidFormatException is thrown. */ @property (readonly, nonatomic) float floatValue; -/*! +/** * @brief The double value of the string as a double. * * If the string contains any non-number characters, an * @ref OFInvalidFormatException is thrown. */ @property (readonly, nonatomic) double doubleValue; -/*! +/** * @brief The string as an array of Unicode characters. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const of_unichar_t *characters OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The string in UTF-16 encoding with native byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const of_char16_t *UTF16String OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The length of the string in UTF-16 characters. */ @property (readonly, nonatomic) size_t UTF16StringLength; -/*! +/** * @brief The string in UTF-32 encoding with native byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const of_char32_t *UTF32String OF_RETURNS_INNER_POINTER; -/*! +/** * @brief The string with leading whitespaces deleted. */ @property (readonly, nonatomic) OFString *stringByDeletingLeadingWhitespaces; -/*! +/** * @brief The string with trailing whitespaces deleted. */ @property (readonly, nonatomic) OFString *stringByDeletingTrailingWhitespaces; -/*! +/** * @brief The string with leading and trailing whitespaces deleted. */ @property (readonly, nonatomic) OFString *stringByDeletingEnclosingWhitespaces; # ifdef OF_HAVE_UNICODE_TABLES -/*! +/** * @brief The string in Unicode Normalization Form D (NFD). */ @property (readonly, nonatomic) OFString *decomposedStringWithCanonicalMapping; -/*! +/** * @brief The string in Unicode Normalization Form KD (NFKD). */ @property (readonly, nonatomic) OFString *decomposedStringWithCompatibilityMapping; # endif # ifdef OF_WINDOWS -/*! +/** * @brief The string with the Windows Environment Strings expanded. */ @property (readonly, nonatomic) OFString *stringByExpandingWindowsEnvironmentStrings; # endif -/*! +/** * @brief Creates a new OFString. * * @return A new, autoreleased OFString */ + (instancetype)string; -/*! +/** * @brief Creates a new OFString from a UTF-8 encoded C string. * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @return A new autoreleased OFString */ + (instancetype)stringWithUTF8String: (const char *)UTF8String; -/*! +/** * @brief Creates a new OFString from a UTF-8 encoded C string with the * specified length. * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @param UTF8StringLength The length of the UTF-8 encoded C string @@ -320,11 +307,11 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; -/*! +/** * @brief Creates a new OFString from a UTF-8 encoded C string without copying * the string, if possible. * * If initialization fails for whatever reason, the passed C string is free'd * if `freeWhenDone` is true. @@ -337,11 +324,11 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone; -/*! +/** * @brief Creates a new OFString from a UTF-8 encoded C string with the * specified length without copying the string, if possible. * * If initialization fails for whatever reason, the passed C string is free'd * if `freeWhenDone` is true. @@ -356,21 +343,21 @@ */ + (instancetype)stringWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone; -/*! +/** * @brief Creates a new OFString from a C string with the specified encoding. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @return A new autoreleased OFString */ + (instancetype)stringWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Creates a new OFString from a C string with the specified encoding * and length. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string @@ -379,29 +366,29 @@ */ + (instancetype)stringWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength; -/*! +/** * @brief Creates a new OFString from OFData with the specified encoding. * * @param data OFData with the contents of the string * @param encoding The encoding in which the string is stored in the OFData * @return An new autoreleased OFString */ + (instancetype)stringWithData: (OFData *)data encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Creates a new OFString from another string. * * @param string A string to initialize the OFString with * @return A new autoreleased OFString */ + (instancetype)stringWithString: (OFString *)string; -/*! +/** * @brief Creates a new OFString from a Unicode string with the specified * length. * * @param characters An array of Unicode characters * @param length The length of the Unicode character array @@ -408,19 +395,19 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithCharacters: (const of_unichar_t *)characters length: (size_t)length; -/*! +/** * @brief Creates a new OFString from a UTF-16 encoded string. * * @param string The UTF-16 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const of_char16_t *)string; -/*! +/** * @brief Creates a new OFString from a UTF-16 encoded string with the * specified length. * * @param string The UTF-16 string * @param length The length of the UTF-16 string @@ -427,11 +414,11 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const of_char16_t *)string length: (size_t)length; -/*! +/** * @brief Creates a new OFString from a UTF-16 encoded string, assuming the * specified byte order if no byte order mark is found. * * @param string The UTF-16 string * @param byteOrder The byte order to assume if there is no byte order mark @@ -438,11 +425,11 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const of_char16_t *)string byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Creates a new OFString from a UTF-16 encoded string with the * specified length, assuming the specified byte order if no byte order * mark is found. * * @param string The UTF-16 string @@ -452,19 +439,19 @@ */ + (instancetype)stringWithUTF16String: (const of_char16_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Creates a new OFString from a UTF-32 encoded string. * * @param string The UTF-32 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const of_char32_t *)string; -/*! +/** * @brief Creates a new OFString from a UTF-32 encoded string with the * specified length. * * @param string The UTF-32 string * @param length The length of the UTF-32 string @@ -471,11 +458,11 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const of_char32_t *)string length: (size_t)length; -/*! +/** * @brief Creates a new OFString from a UTF-32 encoded string, assuming the * specified byte order if no byte order mark is found. * * @param string The UTF-32 string * @param byteOrder The byte order to assume if there is no byte order mark @@ -482,11 +469,11 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const of_char32_t *)string byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Creates a new OFString from a UTF-32 encoded string with the * specified length, assuming the specified byte order if no byte order * mark is found. * * @param string The UTF-32 string @@ -496,11 +483,11 @@ */ + (instancetype)stringWithUTF32String: (const of_char32_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Creates a new OFString from a format string. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -509,20 +496,20 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithFormat: (OFConstantString *)format, ...; # ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a new OFString with the contents of the specified UTF-8 * encoded file. * * @param path The path to the file * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfFile: (OFString *)path; -/*! +/** * @brief Creates a new OFString with the contents of the specified file in the * specified encoding. * * @param path The path to the file * @param encoding The encoding of the file @@ -531,11 +518,11 @@ + (instancetype)stringWithContentsOfFile: (OFString *)path encoding: (of_string_encoding_t)encoding; # endif # if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) -/*! +/** * @brief Creates a new OFString with the contents of the specified URL. * * If the URL's scheme is file, it tries UTF-8 encoding. * * If the URL's scheme is http(s), it tries to detect the encoding from the HTTP @@ -545,11 +532,11 @@ * @param URL The URL to the contents for the string * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfURL: (OFURL *)URL; -/*! +/** * @brief Creates a new OFString with the contents of the specified URL in the * specified encoding. * * @param URL The URL to the contents for the string * @param encoding The encoding to assume @@ -557,20 +544,20 @@ */ + (instancetype)stringWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding; # endif -/*! +/** * @brief Initializes an already allocated OFString from a UTF-8 encoded C * string. * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @return An initialized OFString */ - (instancetype)initWithUTF8String: (const char *)UTF8String; -/*! +/** * @brief Initializes an already allocated OFString from a UTF-8 encoded C * string with the specified length. * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @param UTF8StringLength The length of the UTF-8 encoded C string @@ -577,11 +564,11 @@ * @return An initialized OFString */ - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; -/*! +/** * @brief Initializes an already allocated OFString from an UTF-8 encoded C * string without copying the string, if possible. * * If initialization fails for whatever reason, the passed C string is free'd * if `freeWhenDone` is true. @@ -594,11 +581,11 @@ * @return An initialized OFString */ - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone; -/*! +/** * @brief Initializes an already allocated OFString from an UTF-8 encoded C * string with the specified length without copying the string, if * possible. * * If initialization fails for whatever reason, the passed C string is free'd @@ -614,11 +601,11 @@ */ - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone; -/*! +/** * @brief Initializes an already allocated OFString from a C string with the * specified encoding. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string @@ -625,11 +612,11 @@ * @return An initialized OFString */ - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Initializes an already allocated OFString from a C string with the * specified encoding and length. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string @@ -638,11 +625,11 @@ */ - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength; -/*! +/** * @brief Initializes an already allocated OFString from OFData with the * specified encoding. * * @param data OFData with the contents of the string * @param encoding The encoding in which the string is stored in the OFData @@ -649,19 +636,19 @@ * @return An initialized OFString */ - (instancetype)initWithData: (OFData *)data encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Initializes an already allocated OFString with another string. * * @param string A string to initialize the OFString with * @return An initialized OFString */ - (instancetype)initWithString: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFString with a Unicode string with * the specified length. * * @param characters An array of Unicode characters * @param length The length of the Unicode character array @@ -668,19 +655,19 @@ * @return An initialized OFString */ - (instancetype)initWithCharacters: (const of_unichar_t *)characters length: (size_t)length; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-16 string. * * @param string The UTF-16 string * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const of_char16_t *)string; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-16 string with * the specified length. * * @param string The UTF-16 string * @param length The length of the UTF-16 string @@ -687,11 +674,11 @@ * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-16 string, * assuming the specified byte order if no byte order mark is found. * * @param string The UTF-16 string * @param byteOrder The byte order to assume if there is no byte order mark @@ -698,11 +685,11 @@ * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const of_char16_t *)string byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-16 string with * the specified length, assuming the specified byte order if no byte * order mark is found. * * @param string The UTF-16 string @@ -712,19 +699,19 @@ */ - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-32 string. * * @param string The UTF-32 string * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const of_char32_t *)string; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-32 string with * the specified length * * @param string The UTF-32 string * @param length The length of the UTF-32 string @@ -731,11 +718,11 @@ * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const of_char32_t *)string length: (size_t)length; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-32 string, * assuming the specified byte order if no byte order mark is found. * * @param string The UTF-32 string * @param byteOrder The byte order to assume if there is no byte order mark @@ -742,11 +729,11 @@ * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const of_char32_t *)string byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Initializes an already allocated OFString with a UTF-32 string with * the specified length, assuming the specified byte order if no byte * order mark is found. * * @param string The UTF-32 string @@ -756,11 +743,11 @@ */ - (instancetype)initWithUTF32String: (const of_char32_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder; -/*! +/** * @brief Initializes an already allocated OFString with a format string. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -768,11 +755,11 @@ * @param format A string used as format to initialize the OFString * @return An initialized OFString */ - (instancetype)initWithFormat: (OFConstantString *)format, ...; -/*! +/** * @brief Initializes an already allocated OFString with a format string. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `of_unichar_t` and `%S` for * `const of_unichar_t *`. @@ -783,20 +770,20 @@ */ - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments; # ifdef OF_HAVE_FILES -/*! +/** * @brief Initializes an already allocated OFString with the contents of the * specified file in the specified encoding. * * @param path The path to the file * @return An initialized OFString */ - (instancetype)initWithContentsOfFile: (OFString *)path; -/*! +/** * @brief Initializes an already allocated OFString with the contents of the * specified file in the specified encoding. * * @param path The path to the file * @param encoding The encoding of the file @@ -804,11 +791,11 @@ */ - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (of_string_encoding_t)encoding; # endif -/*! +/** * @brief Initializes an already allocated OFString with the contents of the * specified URL. * * If the URL's scheme is file, it tries UTF-8 encoding. * @@ -819,11 +806,11 @@ * @param URL The URL to the contents for the string * @return An initialized OFString */ - (instancetype)initWithContentsOfURL: (OFURL *)URL; -/*! +/** * @brief Initializes an already allocated OFString with the contents of the * specified URL in the specified encoding. * * @param URL The URL to the contents for the string * @param encoding The encoding to assume @@ -830,11 +817,11 @@ * @return An initialized OFString */ - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Writes the OFString into the specified C string with the specified * encoding. * * @param cString The C string to write into * @param maxLength The maximum number of bytes to write into the C string, @@ -845,11 +832,11 @@ */ - (size_t)getCString: (char *)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Writes the OFString into the specified C string with the specified * encoding, replacing characters that cannot be represented in the * specified encoding with a question mark. * * @param cString The C string to write into @@ -861,11 +848,11 @@ */ - (size_t)getLossyCString: (char *)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Returns the OFString as a C string in the specified encoding. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. @@ -874,11 +861,11 @@ * @return The OFString as a C string in the specified encoding */ - (const char *)cStringWithEncoding: (of_string_encoding_t)encoding OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Returns the OFString as a C string in the specified encoding, * replacing characters that cannot be represented in the specified * encoding with a question mark. * * The result is valid until the autorelease pool is released. If you want to @@ -889,56 +876,56 @@ * @return The OFString as a C string in the specified encoding */ - (const char *)lossyCStringWithEncoding: (of_string_encoding_t)encoding OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Returns the number of bytes the string needs in the specified * encoding. * * @param encoding The encoding for the string * @return The number of bytes the string needs in the specified encoding. */ - (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding; -/*! +/** * @brief Compares the OFString to another OFString without caring about the * case. * * @param otherString A string to compare with * @return An of_comparison_result_t */ - (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString; -/*! +/** * @brief Returns the Unicode character at the specified index. * * @param index The index of the Unicode character to return * @return The Unicode character at the specified index */ - (of_unichar_t)characterAtIndex: (size_t)index; -/*! +/** * @brief Copies the Unicode characters in the specified range to the specified * buffer. * * @param buffer The buffer to store the Unicode characters * @param range The range of the Unicode characters to copy */ - (void)getCharacters: (of_unichar_t *)buffer inRange: (of_range_t)range; -/*! +/** * @brief Returns the range of the first occurrence of the string. * * @param string The string to search * @return The range of the first occurrence of the string or a range with * `OF_NOT_FOUND` as start position if it was not found */ - (of_range_t)rangeOfString: (OFString *)string; -/*! +/** * @brief Returns the range of the string. * * @param string The string to search * @param options Options modifying search behavior.@n * Possible values are: @@ -949,11 +936,11 @@ * `OF_NOT_FOUND` as start position if it was not found */ - (of_range_t)rangeOfString: (OFString *)string options: (int)options; -/*! +/** * @brief Returns the range of the string in the specified range. * * @param string The string to search * @param options Options modifying search behaviour.@n * Possible values are: @@ -966,20 +953,20 @@ */ - (of_range_t)rangeOfString: (OFString *)string options: (int)options range: (of_range_t)range; -/*! +/** * @brief Returns the index of the first character from the set. * * @param characterSet The set of characters to search for * @return The index of the first occurrence of a character from the set or * `OF_NOT_FOUND` if it was not found */ - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet; -/*! +/** * @brief Returns the index of the first character from the set. * * @param characterSet The set of characters to search for * @param options Options modifying search behaviour.@n * Possible values are: @@ -990,11 +977,11 @@ * `OF_NOT_FOUND` if it was not found */ - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (int)options; -/*! +/** * @brief Returns the index of the first character from the set. * * @param characterSet The set of characters to search for * @param options Options modifying search behaviour.@n * Possible values are: @@ -1007,61 +994,100 @@ */ - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (int)options range: (of_range_t)range; -/*! +/** * @brief Returns whether the string contains the specified string. * * @param string The string to search * @return Whether the string contains the specified string */ - (bool)containsString: (OFString *)string; -/*! +/** * @brief Creates a substring with the specified range. * * @param range The range of the substring * @return The substring as a new autoreleased OFString */ - (OFString *)substringWithRange: (of_range_t)range; -/*! +/** + * @brief The value of the string in the specified base as a `long long`. + * + * Leading and trailing whitespaces are ignored. + * + * If the string contains any non-number characters, an + * @ref OFInvalidFormatException is thrown. + * + * If the number is too big to fit into a `long long`, an + * @ref OFOutOfRangeException is thrown. + * + * @param base The base to use. If the base is 0, base 16 is assumed if the + * string starts with 0x (after stripping white spaces). If the + * string starts with 0, base 8 is assumed. Otherwise, base 10 is + * assumed. + * @return The value of the string in the specified base + */ +- (long long)longLongValueWithBase: (int)base; + +/** + * @brief The value of the string in the specified base as an + * `unsigned long long`. + * + * Leading and trailing whitespaces are ignored. + * + * If the string contains any non-number characters, an + * @ref OFInvalidFormatException is thrown. + * + * If the number is too big to fit into an `unsigned long long`, an + * @ref OFOutOfRangeException is thrown. + * + * @param base The base to use. If the base is 0, base 16 is assumed if the + * string starts with 0x (after stripping white spaces). If the + * string starts with 0, base 8 is assumed. Otherwise, base 10 is + * assumed. + * @return The value of the string in the specified base + */ +- (unsigned long long)unsignedLongLongValueWithBase: (int)base; + +/** * @brief Creates a new string by appending another string. * * @param string The string to append * @return A new, autoreleased OFString with the specified string appended */ - (OFString *)stringByAppendingString: (OFString *)string; -/*! +/** * @brief Creates a new string by appending the specified format. * * @param format A format string which generates the string to append * @return A new, autoreleased OFString with the specified format appended */ - (OFString *)stringByAppendingFormat: (OFConstantString *)format, ...; -/*! +/** * @brief Creates a new string by appending the specified format. * * @param format A format string which generates the string to append * @param arguments The arguments used in the format string * @return A new, autoreleased OFString with the specified format appended */ - (OFString *)stringByAppendingFormat: (OFConstantString *)format arguments: (va_list)arguments; -/*! +/** * @brief Creates a new string by prepending another string. * * @param string The string to prepend * @return A new autoreleased OFString with the specified string prepended */ - (OFString *)stringByPrependingString: (OFString *)string; -/*! +/** * @brief Creates a new string by replacing the occurrences of the specified * string with the specified replacement. * * @param string The string to replace * @param replacement The string with which it should be replaced @@ -1068,11 +1094,11 @@ * @return A new string with the occurrences of the specified string replaced */ - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement; -/*! +/** * @brief Creates a new string by replacing the occurrences of the specified * string in the specified range with the specified replacement. * * @param string The string to replace * @param replacement The string with which it should be replaced @@ -1085,37 +1111,37 @@ - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (of_range_t)range; -/*! +/** * @brief Checks whether the string has the specified prefix. * * @param prefix The prefix to check for * @return A boolean whether the string has the specified prefix */ - (bool)hasPrefix: (OFString *)prefix; -/*! +/** * @brief Checks whether the string has the specified suffix. * * @param suffix The suffix to check for * @return A boolean whether the string has the specified suffix */ - (bool)hasSuffix: (OFString *)suffix; -/*! +/** * @brief Separates the string into an array of strings, split by the specified * delimiter. * * @param delimiter The delimiter for separating * @return An autoreleased OFArray with the separated string */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByString: (OFString *)delimiter; -/*! +/** * @brief Separates the string into an array of strings, split by the specified * delimiter. * * @param delimiter The delimiter for separating * @param options Options according to which the string should be separated.@n @@ -1127,21 +1153,21 @@ */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByString: (OFString *)delimiter options: (int)options; -/*! +/** * @brief Separates the string into an array of strings, split by characters in * the specified set. * * @param characterSet The character set for separating * @return An autoreleased OFArray with the separated string */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet; -/*! +/** * @brief Separates the string into an array of strings, split by characters in * the specified set. * * @param characterSet The character set for separating * @param options Options according to which the string should be separated.@n @@ -1153,11 +1179,11 @@ */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet options: (int)options; -/*! +/** * @brief Returns the string in UTF-16 encoding with the specified byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. @@ -1166,11 +1192,11 @@ * @return The string in UTF-16 encoding with the specified byte order */ - (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Returns the string in UTF-32 encoding with the specified byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. @@ -1179,27 +1205,27 @@ * @return The string in UTF-32 encoding with the specified byte order */ - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder OF_RETURNS_INNER_POINTER; -/*! +/** * @brief Returns the string as OFData with the specified encoding. * * @param encoding The encoding to use for the returned OFData * @return The string as OFData with the specified encoding */ - (OFData *)dataWithEncoding: (of_string_encoding_t)encoding; # ifdef OF_HAVE_FILES -/*! +/** * @brief Writes the string into the specified file using UTF-8 encoding. * * @param path The path of the file to write to */ - (void)writeToFile: (OFString *)path; -/*! +/** * @brief Writes the string into the specified file using the specified * encoding. * * @param path The path of the file to write to * @param encoding The encoding to use to write the string into the file @@ -1206,28 +1232,28 @@ */ - (void)writeToFile: (OFString *)path encoding: (of_string_encoding_t)encoding; # endif -/*! +/** * @brief Writes the string to the specified URL using UTF-8 encoding. * * @param URL The URL to write to */ - (void)writeToURL: (OFURL *)URL; -/*! +/** * @brief Writes the string to the specified URL using the specified encoding. * * @param URL The URL to write to * @param encoding The encoding to use to write the string to the URL */ - (void)writeToURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding; # ifdef OF_HAVE_BLOCKS -/*! +/** * Enumerates all lines in the receiver using the specified block. * * @brief block The block to call for each line */ - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block; @@ -1252,15 +1278,15 @@ #include "OFConstantString.h" #include "OFMutableString.h" #ifdef __OBJC__ # import "OFString+CryptoHashing.h" -# import "OFString+JSONValue.h" +# import "OFString+JSONParsing.h" # ifdef OF_HAVE_FILES # import "OFString+PathAdditions.h" # endif -# import "OFString+PropertyListValue.h" +# import "OFString+PropertyListParsing.h" # import "OFString+Serialization.h" # import "OFString+URLEncoding.h" # import "OFString+XMLEscaping.h" # import "OFString+XMLUnescaping.h" #endif Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -15,10 +15,11 @@ * file. */ #include "config.h" +#include #include #include #include #include #include @@ -124,15 +125,15 @@ /* References for static linking */ void _references_to_categories_of_OFString(void) { _OFString_CryptoHashing_reference = 1; - _OFString_JSONValue_reference = 1; + _OFString_JSONParsing_reference = 1; #ifdef OF_HAVE_FILES _OFString_PathAdditions_reference = 1; #endif - _OFString_PropertyListValue_reference = 1; + _OFString_PropertyListParsing_reference = 1; _OFString_Serialization_reference = 1; _OFString_URLEncoding_reference = 1; _OFString_XMLEscaping_reference = 1; _OFString_XMLUnescaping_reference = 1; } @@ -833,29 +834,37 @@ } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { + id ret; + @try { - return [self initWithUTF8String: UTF8String]; + ret = [self initWithUTF8String: UTF8String]; } @finally { if (freeWhenDone) free(UTF8String); } + + return ret; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { + id ret; + @try { - return [self initWithUTF8String: UTF8String - length: UTF8StringLength]; + ret = [self initWithUTF8String: UTF8String + length: UTF8StringLength]; } @finally { if (freeWhenDone) free(UTF8String); } + + return ret; } - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding { @@ -988,11 +997,11 @@ - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (of_string_encoding_t)encoding { char *tmp; - uintmax_t fileSize; + unsigned long long fileSize; @try { void *pool = objc_autoreleasePoolPush(); OFFile *file = nil; @@ -1006,11 +1015,11 @@ errNo: e.errNo]; } objc_autoreleasePoolPop(pool); -# if UINTMAX_MAX > SIZE_MAX +# if ULLONG_MAX > SIZE_MAX if (fileSize > SIZE_MAX) @throw [OFOutOfRangeException exception]; #endif /* @@ -2311,183 +2320,88 @@ objc_autoreleasePoolPop(pool); return array; } -- (intmax_t)decimalValue +- (long long)longLongValue +{ + return [self longLongValueWithBase: 10]; +} + +- (long long)longLongValueWithBase: (int)base { void *pool = objc_autoreleasePoolPush(); - const of_unichar_t *characters = self.characters; - size_t i = 0, length = self.length; - intmax_t value = 0; - bool expectWhitespace = false; - - while (length > 0 && of_ascii_isspace(*characters)) { - characters++; - length--; - } - - if (length == 0) { - objc_autoreleasePoolPop(pool); - return 0; - } - - if (characters[0] == '-' || characters[0] == '+') - i++; - - for (; i < length; i++) { - if (expectWhitespace) { - if (of_ascii_isspace(characters[i])) - continue; - - @throw [OFInvalidFormatException exception]; - } - - if (characters[i] >= '0' && characters[i] <= '9') { - if (INTMAX_MAX / 10 < value || - INTMAX_MAX - value * 10 < characters[i] - '0') - @throw [OFOutOfRangeException exception]; - - value = (value * 10) + (characters[i] - '0'); - } else if (of_ascii_isspace(characters[i])) - expectWhitespace = true; - else - @throw [OFInvalidFormatException exception]; - } - - if (characters[0] == '-') - value *= -1; + const char *UTF8String = self.UTF8String; + char *endPointer = NULL; + long long value; + + errno = 0; + value = strtoll(UTF8String, &endPointer, base); + + if ((value == LLONG_MIN || value == LLONG_MAX) && errno == ERANGE) + @throw [OFOutOfRangeException exception]; + + /* Check if there are any invalid chars left */ + if (endPointer != NULL) + for (; *endPointer != '\0'; endPointer++) + /* Use isspace since strtoll uses the same. */ + if (!isspace((unsigned char)*endPointer)) + @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return value; } -- (uintmax_t)hexadecimalValue -{ - void *pool = objc_autoreleasePoolPush(); - const of_unichar_t *characters = self.characters; - size_t i = 0, length = self.length; - uintmax_t value = 0; - bool expectWhitespace = false, foundValue = false; - - while (length > 0 && of_ascii_isspace(*characters)) { - characters++; - length--; - } - - if (length == 0) { - objc_autoreleasePoolPop(pool); - return 0; - } - - if (length >= 2 && characters[0] == '0' && characters[1] == 'x') - i = 2; - else if (length >= 1 && (characters[0] == 'x' || characters[0] == '$')) - i = 1; - - for (; i < length; i++) { - uintmax_t newValue; - - if (expectWhitespace) { - if (of_ascii_isspace(characters[i])) - continue; - - @throw [OFInvalidFormatException exception]; - } - - if (characters[i] >= '0' && characters[i] <= '9') { - newValue = (value << 4) | (characters[i] - '0'); - foundValue = true; - } else if (characters[i] >= 'A' && characters[i] <= 'F') { - newValue = (value << 4) | (characters[i] - 'A' + 10); - foundValue = true; - } else if (characters[i] >= 'a' && characters[i] <= 'f') { - newValue = (value << 4) | (characters[i] - 'a' + 10); - foundValue = true; - } else if (characters[i] == 'h' || - of_ascii_isspace(characters[i])) { - expectWhitespace = true; - continue; - } else - @throw [OFInvalidFormatException exception]; - - if (newValue < value) - @throw [OFOutOfRangeException exception]; - - value = newValue; - } - - if (!foundValue) - @throw [OFInvalidFormatException exception]; - - objc_autoreleasePoolPop(pool); - - return value; -} - -- (uintmax_t)octalValue -{ - void *pool = objc_autoreleasePoolPush(); - const of_unichar_t *characters = self.characters; - size_t i = 0, length = self.length; - uintmax_t value = 0; - bool expectWhitespace = false; - - while (length > 0 && of_ascii_isspace(*characters)) { - characters++; - length--; - } - - if (length == 0) { - objc_autoreleasePoolPop(pool); - return 0; - } - - for (; i < length; i++) { - uintmax_t newValue; - - if (expectWhitespace) { - if (of_ascii_isspace(characters[i])) - continue; - - @throw [OFInvalidFormatException exception]; - } - - if (characters[i] >= '0' && characters[i] <= '7') - newValue = (value << 3) | (characters[i] - '0'); - else if (of_ascii_isspace(characters[i])) { - expectWhitespace = true; - continue; - } else - @throw [OFInvalidFormatException exception]; - - if (newValue < value) - @throw [OFOutOfRangeException exception]; - - value = newValue; - } +- (unsigned long long)unsignedLongLongValue +{ + return [self unsignedLongLongValueWithBase: 10]; +} + +- (unsigned long long)unsignedLongLongValueWithBase: (int)base +{ + void *pool = objc_autoreleasePoolPush(); + const char *UTF8String = self.UTF8String; + char *endPointer = NULL; + unsigned long long value; + + /* Use isspace since strtoull uses the same. */ + while (isspace((unsigned char)*UTF8String)) + UTF8String++; + + if (*UTF8String == '-') + @throw [OFInvalidFormatException exception]; + + errno = 0; + value = strtoull(UTF8String, &endPointer, base); + + if (value == ULLONG_MAX && errno == ERANGE) + @throw [OFOutOfRangeException exception]; + + /* Check if there are any invalid chars left */ + if (endPointer != NULL) + for (; *endPointer != '\0'; endPointer++) + /* Use isspace since strtoull uses the same. */ + if (!isspace((unsigned char)*endPointer)) + @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return value; } - (float)floatValue { void *pool = objc_autoreleasePoolPush(); - -#if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS) OFString *stripped = self.stringByDeletingEnclosingWhitespaces; if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME) return -INFINITY; -#endif #ifdef HAVE_STRTOF_L const char *UTF8String = self.UTF8String; #else /* @@ -2500,23 +2414,25 @@ withString: decimalPoint].UTF8String; #endif char *endPointer = NULL; float value; - while (of_ascii_isspace(*UTF8String)) - UTF8String++; - + errno = 0; #ifdef HAVE_STRTOF_L value = strtof_l(UTF8String, &endPointer, cLocale); #else value = strtof(UTF8String, &endPointer); #endif + + if (value == HUGE_VALF && errno == ERANGE) + @throw [OFOutOfRangeException exception]; /* Check if there are any invalid chars left */ if (endPointer != NULL) for (; *endPointer != '\0'; endPointer++) - if (!of_ascii_isspace(*endPointer)) + /* Use isspace since strtof uses the same. */ + if (!isspace((unsigned char)*endPointer)) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return value; @@ -2523,21 +2439,18 @@ } - (double)doubleValue { void *pool = objc_autoreleasePoolPush(); - -#if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS) OFString *stripped = self.stringByDeletingEnclosingWhitespaces; if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME) return -INFINITY; -#endif #ifdef HAVE_STRTOD_L const char *UTF8String = self.UTF8String; #else /* @@ -2550,23 +2463,25 @@ withString: decimalPoint].UTF8String; #endif char *endPointer = NULL; double value; - while (of_ascii_isspace(*UTF8String)) - UTF8String++; - + errno = 0; #ifdef HAVE_STRTOD_L value = strtod_l(UTF8String, &endPointer, cLocale); #else value = strtod(UTF8String, &endPointer); #endif + if (value == HUGE_VAL && errno == ERANGE) + @throw [OFOutOfRangeException exception]; + /* Check if there are any invalid chars left */ if (endPointer != NULL) for (; *endPointer != '\0'; endPointer++) - if (!of_ascii_isspace(*endPointer)) + /* Use isspace since strtod uses the same. */ + if (!isspace((unsigned char)*endPointer)) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return value; Index: src/OFSystemInfo.h ================================================================== --- src/OFSystemInfo.h +++ src/OFSystemInfo.h @@ -18,11 +18,11 @@ #import "OFObject.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSystemInfo OFSystemInfo.h ObjFW/OFSystemInfo.h * * @brief A class for querying information about the system. */ OF_SUBCLASSING_RESTRICTED @@ -61,65 +61,65 @@ # ifdef OF_WINDOWS @property (class, readonly, nonatomic, getter=isWindowsNT) bool windowsNT; # endif #endif -/*! +/** * @brief Returns the size of a page. * * @return The size of a page */ + (size_t)pageSize; -/*! +/** * @brief Returns the number of CPUs installed in the system. * * A CPU with multiple cores counts as multiple CPUs. * * @return The number of CPUs installed in the system */ + (size_t)numberOfCPUs; -/*! +/** * @brief The version of ObjFW. * * @return The version of ObjFW */ + (OFString *)ObjFWVersion; -/*! +/** * @brief The major version of ObjFW. * * @return The major version of ObjFW */ + (unsigned int)ObjFWVersionMajor; -/*! +/** * @brief The minor version of ObjFW. * * @return The minor version of ObjFW */ + (unsigned int)ObjFWVersionMinor; -/*! +/** * @brief Returns the name of the operating system the application is running * on. * * @return The name of the operating system the application is running on */ + (nullable OFString *)operatingSystemName; -/*! +/** * @brief Returns the version of the operating system the application is * running on. * * @return The version of the operating system the application is running on */ + (nullable OFString *)operatingSystemVersion; #ifdef OF_HAVE_FILES -/*! +/** * @brief Returns the path where user data for the application can be stored. * * On Unix systems, this adheres to the XDG Base Directory specification.@n * On Mac OS X and iOS, it uses the `NSApplicationSupportDirectory` directory.@n * On Windows, it uses the `APPDATA` environment variable.@n @@ -127,11 +127,11 @@ * * @return The path where user data for the application can be stored */ + (nullable OFString *)userDataPath; -/*! +/** * @brief Returns the path where user configuration for the application can be * stored. * * On Unix systems, this adheres to the XDG Base Directory specification.@n * On Mac OS X and iOS, it uses the `Preferences` directory inside of @@ -142,39 +142,39 @@ * @return The path where user configuration for the application can be stored */ + (nullable OFString *)userConfigPath; #endif -/*! +/** * @brief Returns the vendor of the CPU. * * If the vendor could not be determined, `nil` is returned instead. * * @return The vendor of the CPU */ + (nullable OFString *)CPUVendor; -/*! +/** * @brief Returns the model of the CPU. * * If the model could not be determined, `nil` is returned instead. * * @return The model of the CPU */ + (nullable OFString *)CPUModel; #if defined(OF_X86_64) || defined(OF_X86) || defined(DOXYGEN) -/*! +/** * @brief Returns whether the CPU supports MMX. * * @note This method is only available on x86 and x86_64. * * @return Whether the CPU supports MMX */ + (bool)supportsMMX; -/*! +/** * @brief Returns whether the CPU supports SSE. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -181,11 +181,11 @@ * * @return Whether the CPU supports SSE */ + (bool)supportsSSE; -/*! +/** * @brief Returns whether the CPU supports SSE2. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -192,11 +192,11 @@ * * @return Whether the CPU supports SSE2 */ + (bool)supportsSSE2; -/*! +/** * @brief Returns whether the CPU supports SSE3. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -203,11 +203,11 @@ * * @return Whether the CPU supports SSE3 */ + (bool)supportsSSE3; -/*! +/** * @brief Returns whether the CPU supports SSSE3. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -214,11 +214,11 @@ * * @return Whether the CPU supports SSSE3 */ + (bool)supportsSSSE3; -/*! +/** * @brief Returns whether the CPU supports SSE4.1. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -225,11 +225,11 @@ * * @return Whether the CPU supports SSE4.1 */ + (bool)supportsSSE41; -/*! +/** * @brief Returns whether the CPU supports SSE4.2. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -236,11 +236,11 @@ * * @return Whether the CPU supports SSE4.2 */ + (bool)supportsSSE42; -/*! +/** * @brief Returns whether the CPU supports AVX. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -247,11 +247,11 @@ * * @return Whether the CPU supports AVX */ + (bool)supportsAVX; -/*! +/** * @brief Returns whether the CPU supports AVX2. * * @warning This method only checks CPU support and assumes OS support! * * @note This method is only available on x86 and x86_64. @@ -258,20 +258,20 @@ * * @return Whether the CPU supports AVX2 */ + (bool)supportsAVX2; -/*! +/** * @brief Returns whether the CPU supports AES-NI. * * @note This method is only available on x86 and x86_64. * * @return Whether the CPU supports AES-NI */ + (bool)supportsAESNI; -/*! +/** * @brief Returns whether the CPU supports Intel SHA Extensions. * * @note This method is only available on x86 and x86_64. * * @return Whether the CPU supports Intel SHA Extensions @@ -278,11 +278,11 @@ */ + (bool)supportsSHAExtensions; #endif #if defined(OF_POWERPC) || defined(OF_POWERPC64) -/*! +/** * @brief Returns whether the CPU and OS support AltiVec. * * @note This method is only available on PowerPC and PowerPC 64. * * @return Whether the CPU and OS support AltiVec @@ -289,11 +289,11 @@ */ + (bool)supportsAltiVec; #endif #ifdef OF_WINDOWS -/*! +/** * @brief Returns whether the application is running on Windows NT. * * @note This method is only available on Windows. * * @return Whether the application is running on Windows NT Index: src/OFSystemInfo.m ================================================================== --- src/OFSystemInfo.m +++ src/OFSystemInfo.m @@ -148,13 +148,14 @@ #if defined(OF_IOS) || defined(OF_MACOS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { - OFDictionary *propertyList = [OFString stringWithContentsOfFile: - @"/System/Library/CoreServices/SystemVersion.plist"] - .propertyListValue; + OFDictionary *propertyList = [[OFString + stringWithContentsOfFile: @"/System/Library/CoreServices/" + @"SystemVersion.plist"] + objectByParsingPropertyList]; operatingSystemVersion = [[propertyList objectForKey: @"ProductVersion"] copy]; } @finally { objc_autoreleasePoolPop(pool); Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -18,33 +18,33 @@ #import "OFStreamSocket.h" #import "OFRunLoop.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFTCPSocket; @class OFString; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^of_tcp_socket_async_connect_block_t)(id _Nullable exception); #endif -/*! +/** * @protocol OFTCPSocketDelegate OFTCPSocket.h ObjFW/OFTCPSocket.h * * A delegate for OFTCPSocket. */ @protocol OFTCPSocketDelegate @optional -/*! +/** * @brief A method which is called when a socket connected. * * @param socket The socket which connected * @param host The host connected to * @param port The port on the host connected to @@ -55,11 +55,11 @@ didConnectToHost: (OFString *)host port: (uint16_t)port exception: (nullable id)exception; @end -/*! +/** * @class OFTCPSocket OFTCPSocket.h ObjFW/OFTCPSocket.h * * @brief A class which provides methods to create and use TCP sockets. * * To connect to a server, create a socket and connect it. @@ -70,104 +70,104 @@ OFString *_Nullable _SOCKS5Host; uint16_t _SOCKS5Port; #ifdef OF_WII uint16_t _port; #endif - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFTCPSocket, 4) } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, nullable, copy, nonatomic) OFString *SOCKS5Host; @property (class, nonatomic) uint16_t SOCKS5Port; #endif #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) -/*! +/** * @brief Whether the socket sends keep alives for the connection. * * @warning This is not available on the Wii or Nintendo 3DS! */ @property (nonatomic) bool sendsKeepAlives; #endif #ifndef OF_WII -/*! +/** * @brief Whether sending segments can be delayed. Setting this to NO sets * TCP_NODELAY on the socket. * * @warning This is not available on the Wii! */ @property (nonatomic) bool canDelaySendingSegments; #endif -/*! +/** * @brief The host to use as a SOCKS5 proxy. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *SOCKS5Host; -/*! +/** * @brief The port to use on the SOCKS5 proxy. */ @property (nonatomic) uint16_t SOCKS5Port; -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Sets the global SOCKS5 proxy host to use when creating a new socket * * @param SOCKS5Host The host to use as a SOCKS5 proxy when creating a new * socket */ + (void)setSOCKS5Host: (nullable OFString *)SOCKS5Host; -/*! +/** * @brief Returns the host to use as a SOCKS5 proxy when creating a new socket * * @return The host to use as a SOCKS5 proxy when creating a new socket */ + (nullable OFString *)SOCKS5Host; -/*! +/** * @brief Sets the global SOCKS5 proxy port to use when creating a new socket * * @param SOCKS5Port The port to use as a SOCKS5 proxy when creating a new socket */ + (void)setSOCKS5Port: (uint16_t)SOCKS5Port; -/*! +/** * @brief Returns the port to use as a SOCKS5 proxy when creating a new socket * * @return The port to use as a SOCKS5 proxy when creating a new socket */ + (uint16_t)SOCKS5Port; -/*! +/** * @brief Connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to */ - (void)connectToHost: (OFString *)host port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port; -/*! +/** * @brief Asynchronously connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param runLoopMode The run loop mode in which to perform the async connect @@ -175,11 +175,11 @@ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Asynchronously connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param block The block to execute once the connection has been established @@ -186,11 +186,11 @@ */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port block: (of_tcp_socket_async_connect_block_t)block; -/*! +/** * @brief Asynchronously connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param runLoopMode The run loop mode in which to perform the async connect @@ -200,11 +200,11 @@ port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_tcp_socket_async_connect_block_t)block; #endif -/*! +/** * @brief Bind the socket to the specified host and port. * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be Index: src/OFTLSSocket.h ================================================================== --- src/OFTLSSocket.h +++ src/OFTLSSocket.h @@ -21,18 +21,18 @@ @class OFString; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @protocol OFTLSSocket; -/*! +/** * @protocol OFTLSSocketDelegate OFTLSSocket.h ObjFW/OFTLSSocket.h * * @brief A delegate for classes implementing the OFTLSSocket protocol. */ @protocol OFTLSSocketDelegate @optional -/*! +/** * @brief This callback is called when the TLS socket wants to know if it * should accept the received certificate. * * @note This is only used to verify certain fields of a certificate to allow * for protocol specific verification. The certificate chain is verified @@ -46,58 +46,58 @@ */ - (bool)socket: (id )socket shouldAcceptCertificate: (OFDictionary *)certificate; @end -/*! +/** * @protocol OFTLSSocket OFTLSSocket.h ObjFW/OFTLSSocket.h * * @brief A protocol that should be implemented by 3rd-party libraries * implementing TLS. */ @protocol OFTLSSocket -/*! +/** * @brief The delegate for the TLS socket. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief The path to the X.509 certificate file to use. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *certificateFile; -/*! +/** * @brief The path to the PKCS#8 private key file to use. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *privateKeyFile; -/*! +/** * @brief The passphrase to decrypt the PKCS#8 private key file. * * @warning You have to ensure that this is in secure memory protected from * swapping! This is also the reason why this is not an OFString. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) const char *privateKeyPassphrase; -/*! +/** * @brief Whether certificates are verified. * * The default is enabled. */ @property (nonatomic) bool verifiesCertificates; -/*! +/** * @brief Initializes the TLS socket with the specified TCP socket as its * underlying socket. * * @param socket The TCP socket to use as underlying socket */ - (instancetype)initWithSocket: (OFTCPSocket *)socket; -/*! +/** * @brief Initiates the TLS handshake. * * @note This is only useful if you used @ref initWithSocket: to start TLS on * a TCP socket which is already connected! * @@ -104,11 +104,11 @@ * @param host The host to expect for certificate verification. * May be `nil` if certificate verification is disabled. */ - (void)startTLSWithExpectedHost: (nullable OFString *)host; -/*! +/** * @brief Sets the path to the X.509 certificate file to use for the specified * SNI host. * * @param SNIHost The SNI host for which the path of the X.509 certificate file * should be set @@ -116,11 +116,11 @@ * @param certificateFile The path to the X.509 certificate file */ - (void)setCertificateFile: (OFString *)certificateFile forSNIHost: (OFString *)SNIHost; -/*! +/** * @brief Returns the path of the X.509 certificate file used by the TLS socket * for the specified SNI host. * * @param SNIHost The SNI host for which the path of the X.509 certificate file * should be returned @@ -128,11 +128,11 @@ * @return The path of the X.509 certificate file used by the TLS socket for * the specified SNI host */ - (nullable OFString *)certificateFileForSNIHost: (OFString *)SNIHost; -/*! +/** * @brief Sets the path to the PKCS#8 private key file to use for the specified * SNI host. * * @param privateKeyFile The path to the PKCS#8 private key file * @param SNIHost The SNI host for which the path to the PKCS#8 private key @@ -139,11 +139,11 @@ * file should be set */ - (void)setPrivateKeyFile: (OFString *)privateKeyFile forSNIHost: (OFString *)SNIHost; -/*! +/** * @brief Returns the path of the PKCS#8 private key file used by the TLS * socket for the specified SNI host. * * @param SNIHost The SNI host for which the path of the PKCS#8 private key * file should be returned @@ -151,11 +151,11 @@ * @return The path of the PKCS#8 private key file used by the TLS socket for * the specified SNI host */ - (nullable OFString *)privateKeyFileForSNIHost: (OFString *)SNIHost; -/*! +/** * @brief Sets the passphrase to decrypt the PKCS#8 private key file for the * specified SNI host. * * @warning You have to ensure that this is in secure memory protected from * swapping! This is also the reason why this is not an OFString. @@ -166,11 +166,11 @@ * private key file should be set */ - (void)setPrivateKeyPassphrase: (const char *)privateKeyPassphrase forSNIHost: (OFString *)SNIHost; -/*! +/** * @brief Returns the passphrase to decrypt the PKCS#8 private key file for the * specified SNI host. * * @warning You should not copy this to insecure memory which is swappable! * Index: src/OFTarArchive.h ================================================================== --- src/OFTarArchive.h +++ src/OFTarArchive.h @@ -22,11 +22,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFStream; -/*! +/** * @class OFTarArchive OFTarArchive.h ObjFW/OFTarArchive.h * * @brief A class for accessing and manipulating tar archives. */ OF_SUBCLASSING_RESTRICTED @@ -40,27 +40,26 @@ } _mode; of_string_encoding_t _encoding; OFStream *_Nullable _lastReturnedStream; } -/*! +/** * @brief The encoding to use for the archive. Defaults to UTF-8. */ @property (nonatomic) of_string_encoding_t encoding; -/*! +/** * @brief A stream for reading the current entry. * * @note This is only available in read mode. * - * @note The returned stream only conforms to @ref OFReadyForReadingObserving if - * the underlying stream does so, too. + * @note The returned stream conforms to @ref OFReadyForReadingObserving if the + * underlying stream does so, too. */ -@property (readonly, nonatomic) - OFStream *streamForReadingCurrentEntry; +@property (readonly, nonatomic) OFStream *streamForReadingCurrentEntry; -/*! +/** * @brief Creates a new OFTarArchive object with the specified stream. * * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, @@ -70,11 +69,11 @@ */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a new OFTarArchive object with the specified file. * * @param path The path to the tar archive * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing @@ -85,11 +84,11 @@ mode: (OFString *)mode; #endif - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFTarArchive object with the * specified stream. * * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. @@ -100,11 +99,11 @@ */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES -/*! +/** * @brief Initializes an already allocated OFTarArchive object with the * specified file. * * @param path The path to the tar archive * @param mode The mode for the tar file. Valid modes are "r" for reading, @@ -114,11 +113,11 @@ */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; #endif -/*! +/** * @brief Returns the next entry from the tar archive or `nil` if all entries * have been read. * * @note This is only available in read mode. * @@ -131,17 +130,17 @@ * @return The next entry from the tar archive or `nil` if all entries have * been read */ - (nullable OFTarArchiveEntry *)nextEntry; -/*! +/** * @brief Returns a stream for writing the specified entry. * * @note This is only available in write and append mode. * - * @note The returned stream only conforms to @ref OFReadyForWritingObserving if - * the underlying stream does so, too. + * @note The returned stream conforms to @ref OFReadyForWritingObserving if the + * underlying stream does so, too. * * @warning Calling @ref nextEntry will invalidate all streams returned by * @ref streamForReadingCurrentEntry or * @ref streamForWritingEntry:! Reading from or writing to an * invalidated stream will throw an @ref OFReadFailedException or @@ -148,15 +147,14 @@ * @ref OFWriteFailedException! * * @param entry The entry for which a stream for writing should be returned * @return A stream for writing the specified entry */ -- (OFStream *) - streamForWritingEntry: (OFTarArchiveEntry *)entry; +- (OFStream *)streamForWritingEntry: (OFTarArchiveEntry *)entry; -/*! +/** * @brief Closes the OFTarArchive. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFTarArchive.m ================================================================== --- src/OFTarArchive.m +++ src/OFTarArchive.m @@ -212,11 +212,11 @@ entry: entry]; return entry; } -- (OFStream *)streamForReadingCurrentEntry +- (OFStream *)streamForReadingCurrentEntry { if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @@ -224,12 +224,11 @@ return [[(OFTarArchiveFileReadStream *)_lastReturnedStream retain] autorelease]; } -- (OFStream *) - streamForWritingEntry: (OFTarArchiveEntry *)entry +- (OFStream *)streamForWritingEntry: (OFTarArchiveEntry *)entry { void *pool; if (_mode != OF_TAR_ARCHIVE_MODE_WRITE && _mode != OF_TAR_ARCHIVE_MODE_APPEND) Index: src/OFTarArchiveEntry.h ================================================================== --- src/OFTarArchiveEntry.h +++ src/OFTarArchiveEntry.h @@ -17,129 +17,129 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFDate; -/*! +/** * @brief The type of the archive entry. */ typedef enum of_tar_archive_entry_type_t { - /*! Normal file */ + /** Normal file */ OF_TAR_ARCHIVE_ENTRY_TYPE_FILE = '0', - /*! Hard link */ + /** Hard link */ OF_TAR_ARCHIVE_ENTRY_TYPE_LINK = '1', - /*! Symbolic link */ + /** Symbolic link */ OF_TAR_ARCHIVE_ENTRY_TYPE_SYMLINK = '2', - /*! Character device */ + /** Character device */ OF_TAR_ARCHIVE_ENTRY_TYPE_CHARACTER_DEVICE = '3', - /*! Block device */ + /** Block device */ OF_TAR_ARCHIVE_ENTRY_TYPE_BLOCK_DEVICE = '4', - /*! Directory */ + /** Directory */ OF_TAR_ARCHIVE_ENTRY_TYPE_DIRECTORY = '5', - /*! FIFO */ + /** FIFO */ OF_TAR_ARCHIVE_ENTRY_TYPE_FIFO = '6', - /*! Contiguous file */ + /** Contiguous file */ OF_TAR_ARCHIVE_ENTRY_TYPE_CONTIGUOUS_FILE = '7', } of_tar_archive_entry_type_t; -/*! +/** * @class OFTarArchiveEntry OFTarArchiveEntry.h ObjFW/OFTarArchiveEntry.h * * @brief A class which represents an entry of a tar archive. */ @interface OFTarArchiveEntry: OFObject { OFString *_fileName; - uint32_t _mode; - uint64_t _size; - uint32_t _UID, _GID; + unsigned long _mode; + unsigned long long _size; + unsigned long _UID, _GID; OFDate *_modificationDate; of_tar_archive_entry_type_t _type; OFString *_Nullable _targetFileName; OFString *_Nullable _owner, *_Nullable _group; - uint32_t _deviceMajor, _deviceMinor; - OF_RESERVE_IVARS(4) + unsigned long _deviceMajor, _deviceMinor; + OF_RESERVE_IVARS(OFTarArchiveEntry, 4) } -/*! +/** * @brief The file name of the entry. */ @property (readonly, copy, nonatomic) OFString *fileName; -/*! +/** * @brief The mode of the entry. */ -@property (readonly, nonatomic) uint32_t mode; +@property (readonly, nonatomic) unsigned long mode; -/*! +/** * @brief The UID of the owner. */ -@property (readonly, nonatomic) uint32_t UID; +@property (readonly, nonatomic) unsigned long UID; -/*! +/** * @brief The GID of the group. */ -@property (readonly, nonatomic) uint32_t GID; +@property (readonly, nonatomic) unsigned long GID; -/*! +/** * @brief The size of the file. */ -@property (readonly, nonatomic) uint64_t size; +@property (readonly, nonatomic) unsigned long long size; -/*! +/** * @brief The date of the last modification of the file. */ @property (readonly, retain, nonatomic) OFDate *modificationDate; -/*! +/** * @brief The type of the archive entry. * * See @ref of_tar_archive_entry_type_t. */ @property (readonly, nonatomic) of_tar_archive_entry_type_t type; -/*! +/** * @brief The file name of the target (for a hard link or symbolic link). */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *targetFileName; -/*! +/** * @brief The owner of the file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *owner; -/*! +/** * @brief The group of the file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *group; -/*! +/** * @brief The device major (if the file is a device). */ -@property (readonly, nonatomic) uint32_t deviceMajor; +@property (readonly, nonatomic) unsigned long deviceMajor; -/*! +/** * @brief The device major (if the file is a device). */ -@property (readonly, nonatomic) uint32_t deviceMinor; +@property (readonly, nonatomic) unsigned long deviceMinor; -/*! +/** * @brief Creates a new OFTarArchiveEntry with the specified file name. * * @param fileName The file name for the OFTarArchiveEntry * @return A new, autoreleased OFTarArchiveEntry */ + (instancetype)entryWithFileName: (OFString *)fileName; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFTarArchiveEntry with the specified * file name. * * @param fileName The file name for the OFTarArchiveEntry * @return An initialized OFTarArchiveEntry Index: src/OFTarArchiveEntry.m ================================================================== --- src/OFTarArchiveEntry.m +++ src/OFTarArchiveEntry.m @@ -51,24 +51,25 @@ for (size_t i = cStringLength; i < length; i++) buffer[i] = '\0'; } -static uintmax_t -octalValueFromBuffer(const unsigned char *buffer, size_t length, uintmax_t max) +static unsigned long long +octalValueFromBuffer(const unsigned char *buffer, size_t length, + unsigned long long max) { - uintmax_t value = 0; + unsigned long long value = 0; if (length == 0) return 0; if (buffer[0] == 0x80) { for (size_t i = 1; i < length; i++) value = (value << 8) | buffer[i]; } else - value = stringFromBuffer(buffer, length, - OF_STRING_ENCODING_ASCII).octalValue; + value = [stringFromBuffer(buffer, length, + OF_STRING_ENCODING_ASCII) unsignedLongLongValueWithBase: 8]; if (value > max) @throw [OFOutOfRangeException exception]; return value; @@ -93,22 +94,22 @@ @try { void *pool = objc_autoreleasePoolPush(); OFString *targetFileName; _fileName = [stringFromBuffer(header, 100, encoding) copy]; - _mode = (uint32_t)octalValueFromBuffer( - header + 100, 8, UINT32_MAX); - _UID = (uint32_t)octalValueFromBuffer( - header + 108, 8, UINT32_MAX); - _GID = (uint32_t)octalValueFromBuffer( - header + 116, 8, UINT32_MAX); - _size = (uint64_t)octalValueFromBuffer( - header + 124, 12, UINT64_MAX); + _mode = (unsigned long)octalValueFromBuffer( + header + 100, 8, ULONG_MAX); + _UID = (unsigned long)octalValueFromBuffer( + header + 108, 8, ULONG_MAX); + _GID = (unsigned long)octalValueFromBuffer( + header + 116, 8, ULONG_MAX); + _size = (unsigned long long)octalValueFromBuffer( + header + 124, 12, ULLONG_MAX); _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: (of_time_interval_t)octalValueFromBuffer( - header + 136, 12, UINTMAX_MAX)]; + header + 136, 12, ULLONG_MAX)]; _type = header[156]; targetFileName = stringFromBuffer(header + 157, 100, encoding); if (targetFileName.length > 0) _targetFileName = [targetFileName copy]; @@ -122,14 +123,14 @@ _owner = [stringFromBuffer(header + 265, 32, encoding) copy]; _group = [stringFromBuffer(header + 297, 32, encoding) copy]; - _deviceMajor = (uint32_t)octalValueFromBuffer( - header + 329, 8, UINT32_MAX); - _deviceMinor = (uint32_t)octalValueFromBuffer( - header + 337, 8, UINT32_MAX); + _deviceMajor = (unsigned long)octalValueFromBuffer( + header + 329, 8, ULONG_MAX); + _deviceMinor = (unsigned long)octalValueFromBuffer( + header + 337, 8, ULONG_MAX); prefix = stringFromBuffer(header + 345, 155, encoding); if (prefix.length > 0) { OFString *fileName = [OFString stringWithFormat: @"%@/%@", @@ -206,26 +207,26 @@ - (OFString *)fileName { return _fileName; } -- (uint32_t)mode +- (unsigned long)mode { return _mode; } -- (uint32_t)UID +- (unsigned long)UID { return _UID; } -- (uint32_t)GID +- (unsigned long)GID { return _GID; } -- (uint64_t)size +- (unsigned long long)size { return _size; } - (OFDate *)modificationDate @@ -251,16 +252,16 @@ - (OFString *)group { return _group; } -- (uint32_t)deviceMajor +- (unsigned long)deviceMajor { return _deviceMajor; } -- (uint32_t)deviceMinor +- (unsigned long)deviceMinor { return _deviceMinor; } - (OFString *)description @@ -292,11 +293,11 @@ - (void)of_writeToStream: (OFStream *)stream encoding: (of_string_encoding_t)encoding { unsigned char buffer[512]; - uint64_t modificationDate; + unsigned long long modificationDate; uint16_t checksum = 0; stringToBuffer(buffer, _fileName, 100, encoding); stringToBuffer(buffer + 100, [OFString stringWithFormat: @"%06" PRIo16 " ", _mode], 8, @@ -310,11 +311,11 @@ stringToBuffer(buffer + 124, [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12, OF_STRING_ENCODING_ASCII); modificationDate = _modificationDate.timeIntervalSince1970; stringToBuffer(buffer + 136, - [OFString stringWithFormat: @"%011" PRIo64 " ", modificationDate], + [OFString stringWithFormat: @"%011llo", modificationDate], 12, OF_STRING_ENCODING_ASCII); /* * During checksumming, the checksum field is expected to be set to 8 * spaces. Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -23,29 +23,29 @@ # import "thread.h" #endif OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFDate; #ifdef OF_HAVE_SOCKETS @class OFDNSResolver; #endif @class OFRunLoop; @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); #if defined(OF_HAVE_THREADS) && defined(OF_HAVE_BLOCKS) -/*! +/** * @brief A block to be executed in a new thread. * * @return The object which should be returned when the thread is joined */ typedef id _Nullable (^of_thread_block_t)(void); #endif -/*! +/** * @class OFThread OFThread.h ObjFW/OFThread.h * * @brief A class which provides portable threads. * * To use it, you should create a new class derived from it and reimplement @@ -86,11 +86,11 @@ OFMutableDictionary *_threadDictionary; OFString *_Nullable _name; # ifdef OF_HAVE_SOCKETS OFDNSResolver *_DNSResolver; # endif - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFThread, 4) } #endif #ifdef OF_HAVE_CLASS_PROPERTIES # ifdef OF_HAVE_THREADS @@ -105,11 +105,11 @@ @property (class, readonly, nonatomic) OFDNSResolver *DNSResolver; # endif #endif #ifdef OF_HAVE_THREADS -/*! +/** * @brief The name for the thread to use when starting it. * * @note While this can be changed after the thread has been started, it will * have no effect once the thread started. If you want to change the name * of the current thread after it has been started, look at the class @@ -116,23 +116,23 @@ * method @ref setName:. */ @property OF_NULLABLE_PROPERTY (copy) OFString *name; # ifdef OF_HAVE_BLOCKS -/*! +/** * @brief The block to execute in the thread. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) of_thread_block_t threadBlock; # endif -/*! +/** * @brief The run loop for the thread. */ @property (readonly, nonatomic) OFRunLoop *runLoop; -/*! +/** * @brief The priority of the thread. * * @note This has to be set before the thread is started! * * This is a value between -1.0 (meaning lowest priority that still schedules) @@ -139,164 +139,164 @@ * and +1.0 (meaning highest priority that still allows getting preempted) * with normal priority being 0.0 (meaning being the same as the main thread). */ @property (nonatomic) float priority; -/*! +/** * @brief The stack size of the thread. * * @note This has to be set before the thread is started! */ @property (nonatomic) size_t stackSize; -/*! +/** * @brief Whether the thread supports sockets. * * Some operating systems such as AmigaOS need special per-thread * initialization of sockets. If you intend to use sockets in the thread, set * this property to true before starting the thread. */ @property (nonatomic) bool supportsSockets; -/*! +/** * @brief Creates a new thread. * * @return A new, autoreleased thread */ + (instancetype)thread; # ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Creates a new thread with the specified block. * * @param threadBlock A block which is executed by the thread * @return A new, autoreleased thread */ + (instancetype)threadWithThreadBlock: (of_thread_block_t)threadBlock; # endif -/*! +/** * @brief Returns the current thread. * * @return The current thread */ + (nullable OFThread *)currentThread; -/*! +/** * @brief Returns the main thread. * * @return The main thread */ + (nullable OFThread *)mainThread; -/*! +/** * @brief Returns whether the current thread is the main thread. * * @return Whether the current thread is the main thread. */ + (bool)isMainThread; -/*! +/** * @brief Returns a dictionary to store thread-specific data, meaning it * returns a different dictionary for every thread. * * @return A dictionary to store thread-specific data */ + (nullable OFMutableDictionary *)threadDictionary; #endif #ifdef OF_HAVE_SOCKETS -/*! +/** * @brief Returns the DNS resolver for the current thread. * * @return The DNS resolver for the current thread */ + (OFDNSResolver *)DNSResolver; #endif -/*! +/** * @brief Suspends execution of the current thread for the specified time * interval. * * @param timeInterval The number of seconds to sleep */ + (void)sleepForTimeInterval: (of_time_interval_t)timeInterval; -/*! +/** * @brief Suspends execution of the current thread until the specified date. * * @param date The date to wait for */ + (void)sleepUntilDate: (OFDate *)date; -/*! +/** * @brief Yields a processor voluntarily and moves the thread to the end of the * queue for its priority. */ + (void)yield; #ifdef OF_HAVE_THREADS -/*! +/** * @brief Terminates the current thread, letting it return `nil`. */ + (void)terminate OF_NO_RETURN; -/*! +/** * @brief Terminates the current thread, letting it return the specified object. * * @param object The object which the terminated thread will return */ + (void)terminateWithObject: (nullable id)object OF_NO_RETURN; -/*! +/** * @brief Sets the name of the current thread. * * Unlike the instance method, this can be used after the thread has been * started. * * @param name The new name for the current thread. */ + (void)setName: (nullable OFString *)name; -/*! +/** * @brief Returns the name of the current thread. * * @return The name of the current thread. */ + (nullable OFString *)name; # ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Initializes an already allocated thread with the specified block. * * @param threadBlock A block which is executed by the thread * @return An initialized OFThread. */ - (instancetype)initWithThreadBlock: (of_thread_block_t)threadBlock; # endif -/*! +/** * @brief The main routine of the thread. You need to reimplement this! * * @return The object the join method should return when called for this thread */ - (nullable id)main; -/*! +/** * @brief This routine is executed when the thread's main method has finished * executing or terminate has been called. * * @note Be sure to call [super handleTermination]! */ - (void)handleTermination OF_REQUIRES_SUPER; -/*! +/** * @brief Starts the thread. */ - (void)start; -/*! +/** * @brief Joins a thread. * * @return The object returned by the main method of the thread. */ - (id)join; Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -254,11 +254,11 @@ svcSleepThread((int64_t)(timeInterval * 1000000000)); #elif defined(HAVE_NANOSLEEP) struct timespec rqtp; rqtp.tv_sec = (time_t)timeInterval; - rqtp.tv_nsec = (timeInterval - rqtp.tv_sec) * 1000000000; + rqtp.tv_nsec = (long)((timeInterval - rqtp.tv_sec) * 1000000000); if (rqtp.tv_sec != trunc(timeInterval)) @throw [OFOutOfRangeException exception]; nanosleep(&rqtp, NULL); @@ -334,11 +334,11 @@ if (name != nil) of_thread_set_name( [name cStringWithEncoding: [OFLocale encoding]]); else - of_thread_set_name(class_getName(self.class)); + of_thread_set_name(class_getName([self class])); } + (OFString *)name { return [OFThread currentThread].name; Index: src/OFThreadPool.h ================================================================== --- src/OFThreadPool.h +++ src/OFThreadPool.h @@ -17,14 +17,14 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block for a job which should be executed in a thread pool. */ typedef void (^of_thread_pool_block_t)(void); #endif @@ -31,11 +31,11 @@ @class OFCondition; @class OFList OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFThreadPoolJob; -/*! +/** * @class OFThreadPool OFThreadPool.h ObjFW/OFThreadPool.h * * @brief A class providing a pool of reusable threads. * * @note When the thread pool is released, all threads will terminate after @@ -54,43 +54,43 @@ OFCondition *_queueCondition; volatile int _doneCount; OFCondition *_countCondition; } -/*! +/** * @brief The size of the thread pool. */ @property (readonly, nonatomic) size_t size; -/*! +/** * @brief Returns a new thread pool with one thread for each core in the system. * * @warning If for some reason the number of cores in the system could not be * determined, the pool will only have one thread! * * @return A new thread pool with one thread for each core in the system */ + (instancetype)threadPool; -/*! +/** * @brief Returns a new thread pool with the specified number of threads. * * @param size The number of threads for the pool * @return A new thread pool with the specified number of threads */ + (instancetype)threadPoolWithSize: (size_t)size; -/*! +/** * @brief Initializes an already allocated OFThreadPool with the specified * number of threads. * * @param size The number of threads for the pool * @return An initialized OFThreadPool with the specified number of threads */ - (instancetype)initWithSize: (size_t)size OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Execute the specified selector on the specified target with the * specified object as soon as a thread is ready. * * @param target The target on which to perform the selector * @param selector The selector to perform on the target @@ -99,20 +99,20 @@ - (void)dispatchWithTarget: (id)target selector: (SEL)selector object: (nullable id)object; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Executes the specified block as soon as a thread is ready. * * @param block The block to execute */ - (void)dispatchWithBlock: (of_thread_pool_block_t)block; #endif -/*! +/** * @brief Waits until all jobs are done. */ - (void)waitUntilDone; @end OF_ASSUME_NONNULL_END Index: src/OFTimer.h ================================================================== --- src/OFTimer.h +++ src/OFTimer.h @@ -18,28 +18,28 @@ #import "OFObject.h" #import "OFRunLoop.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFTimer; @class OFDate; #ifdef OF_HAVE_THREADS @class OFCondition; #endif #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief A block to execute when a timer fires. * * @param timer The timer which fired */ typedef void (^of_timer_block_t)(OFTimer *timer); #endif -/*! +/** * @class OFTimer OFTimer.h ObjFW/OFTimer.h * * @brief A class for creating and firing timers. */ OF_SUBCLASSING_RESTRICTED @@ -62,37 +62,37 @@ #endif OFRunLoop *_Nullable _inRunLoop; of_run_loop_mode_t _Nullable _inRunLoopMode; } -/*! +/** * @brief The time interval in which the timer will repeat, if it is a * repeating timer. */ @property (readonly, nonatomic) of_time_interval_t timeInterval; -/*! +/** * @brief Whether the timer is repeating. */ @property (readonly, nonatomic, getter=isRepeating) bool repeating; -/*! +/** * @brief Whether the timer is valid. */ @property (readonly, nonatomic, getter=isValid) bool valid; -/*! +/** * @brief The next date at which the timer will fire. * * If the timer is already scheduled in a run loop, it will be rescheduled. * Note that rescheduling is an expensive operation, though it still might be * preferable to reschedule instead of invalidating the timer and creating a * new one. */ @property (copy, nonatomic) OFDate *fireDate; -/*! +/** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -102,11 +102,11 @@ + (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval target: (id)target selector: (SEL)selector repeats: (bool)repeats; -/*! +/** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -118,11 +118,11 @@ target: (id)target selector: (SEL)selector object: (nullable id)object repeats: (bool)repeats; -/*! +/** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -138,11 +138,11 @@ selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 repeats: (bool)repeats; -/*! +/** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -161,11 +161,11 @@ object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 repeats: (bool)repeats; -/*! +/** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -188,11 +188,11 @@ object: (nullable id)object3 object: (nullable id)object4 repeats: (bool)repeats; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param repeats Whether the timer repeats after it has been executed * @param block The block to invoke when the timer fires @@ -201,11 +201,11 @@ + (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval repeats: (bool)repeats block: (of_timer_block_t)block; #endif -/*! +/** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -215,11 +215,11 @@ + (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval target: (id)target selector: (SEL)selector repeats: (bool)repeats; -/*! +/** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -231,11 +231,11 @@ target: (id)target selector: (SEL)selector object: (nullable id)object repeats: (bool)repeats; -/*! +/** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -251,11 +251,11 @@ selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 repeats: (bool)repeats; -/*! +/** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -274,11 +274,11 @@ object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 repeats: (bool)repeats; -/*! +/** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target @@ -301,11 +301,11 @@ object: (nullable id)object3 object: (nullable id)object4 repeats: (bool)repeats; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param repeats Whether the timer repeats after it has been executed * @param block The block to invoke when the timer fires @@ -316,11 +316,11 @@ block: (of_timer_block_t)block; #endif - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is @@ -334,11 +334,11 @@ interval: (of_time_interval_t)interval target: (id)target selector: (SEL)selector repeats: (bool)repeats; -/*! +/** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is @@ -354,11 +354,11 @@ target: (id)target selector: (SEL)selector object: (nullable id)object repeats: (bool)repeats; -/*! +/** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is @@ -378,11 +378,11 @@ selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 repeats: (bool)repeats; -/*! +/** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is @@ -405,11 +405,11 @@ object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 repeats: (bool)repeats; -/*! +/** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is @@ -436,11 +436,11 @@ object: (nullable id)object3 object: (nullable id)object4 repeats: (bool)repeats; #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is @@ -453,25 +453,25 @@ interval: (of_time_interval_t)interval repeats: (bool)repeats block: (of_timer_block_t)block; #endif -/*! +/** * @brief Fires the timer, meaning it will execute the specified selector on the * target. */ - (void)fire; -/*! +/** * @brief Invalidates the timer, preventing it from firing. */ - (void)invalidate; #ifdef OF_HAVE_THREADS -/*! +/** * @brief Waits until the timer fired. */ - (void)waitUntilDone; #endif @end OF_ASSUME_NONNULL_END Index: src/OFTriple.h ================================================================== --- src/OFTriple.h +++ src/OFTriple.h @@ -17,11 +17,11 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFTriple OFTriple.h ObjFW/OFTriple.h * * @brief A class for storing a triple of three objects. */ @interface OFTriple OF_GENERIC(FirstType, SecondType, ThirdType): @@ -33,32 +33,32 @@ #endif { FirstType _Nullable _firstObject; SecondType _Nullable _secondObject; ThirdType _Nullable _thirdObject; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFTriple, 4) } -/*! +/** * @brief The first object of the triple. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic, retain) FirstType firstObject; -/*! +/** * @brief The second object of the triple. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic, retain) SecondType secondObject; -/*! +/** * @brief The third object of the triple. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic, retain) ThirdType thirdObject; -/*! +/** * @brief Creates a new OFTriple with the specified objects. * * @param firstObject The first object for the triple * @param secondObject The second object for the triple * @param thirdObject The second object for the triple @@ -66,11 +66,11 @@ */ + (instancetype)tripleWithFirstObject: (nullable FirstType)firstObject secondObject: (nullable SecondType)secondObject thirdObject: (nullable ThirdType)thirdObject; -/*! +/** * @brief Initializes an already allocated OFTriple with the specified objects. * * @param firstObject The first object for the triple * @param secondObject The second object for the triple * @param thirdObject The second object for the triple Index: src/OFUDPSocket.h ================================================================== --- src/OFUDPSocket.h +++ src/OFUDPSocket.h @@ -19,19 +19,19 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @protocol OFUDPSocketDelegate OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A delegate for OFUDPSocket. */ @protocol OFUDPSocketDelegate @end -/*! +/** * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A class which provides methods to create and use UDP sockets. * * Addresses are of type @ref of_socket_address_t. You can use the current @@ -51,23 +51,23 @@ @interface OFUDPSocket: OFDatagramSocket { #ifdef OF_WII uint16_t _port; #endif - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFUDPSocket, 4) } -/*! +/** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Binds the socket to the specified host and port. * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be Index: src/OFURL.h ================================================================== --- src/OFURL.h +++ src/OFURL.h @@ -20,14 +20,15 @@ #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); +@class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFNumber; @class OFString; -/*! +/** * @class OFURL OFURL.h ObjFW/OFURL.h * * @brief A class for parsing URLs and accessing parts of it. */ @interface OFURL: OFObject @@ -35,123 +36,137 @@ OFString *_Nullable _URLEncodedScheme, *_Nullable _URLEncodedHost; OFNumber *_Nullable _port; OFString *_Nullable _URLEncodedUser, *_Nullable _URLEncodedPassword; OFString *_Nullable _URLEncodedPath; OFString *_Nullable _URLEncodedQuery, *_Nullable _URLEncodedFragment; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFURL, 4) } -/*! +/** * @brief The scheme part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *scheme; -/*! +/** * @brief The scheme part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedScheme; -/*! +/** * @brief The host part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *host; -/*! +/** * @brief The host part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedHost; -/*! +/** * @brief The port part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFNumber *port; -/*! +/** * @brief The user part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *user; -/*! +/** * @brief The user part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedUser; -/*! +/** * @brief The password part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *password; -/*! +/** * @brief The password part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedPassword; -/*! +/** * @brief The path part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *path; -/*! +/** * @brief The path part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedPath; -/*! +/** * @brief The path of the URL split into components. * * The first component must always be `/` to designate the root. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFArray OF_GENERIC(OFString *) *pathComponents; -/*! +/** * @brief The last path component of the URL. * * Returns the empty string if the path is the root. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *lastPathComponent; -/*! +/** * @brief The query part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *query; -/*! +/** * @brief The query part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedQuery; -/*! +/** + * @brief The query part of the URL as a dictionary. + * + * For example, a query like `key1=value1&key2=value2` would correspond to the + * following dictionary: + * + * @{ + * @"key1": "value1", + * @"key2": "value2" + * } + */ +@property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) + OFDictionary OF_GENERIC(OFString *, OFString *) *queryDictionary; + +/** * @brief The fragment part of the URL. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *fragment; -/*! +/** * @brief The fragment part of the URL in URL-encoded form. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedFragment; -/*! +/** * @brief The URL as a string. */ @property (readonly, nonatomic) OFString *string; -/*! +/** * @brief The URL with relative sub paths resolved. */ @property (readonly, nonatomic) OFURL *URLByStandardizingPath; #ifdef OF_HAVE_FILES -/*! +/** * @brief The local file system representation for a file URL. * * @note This only exists for URLs with the file scheme and throws an exception * otherwise. * @@ -158,19 +173,19 @@ */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *fileSystemRepresentation; #endif -/*! +/** * @brief Creates a new URL with the specified string. * * @param string A string describing a URL * @return A new, autoreleased OFURL */ + (instancetype)URLWithString: (OFString *)string; -/*! +/** * @brief Creates a new URL with the specified string relative to the * specified URL. * * @param string A string describing a URL * @param URL An URL to which the string is relative @@ -178,11 +193,11 @@ */ + (instancetype)URLWithString: (OFString *)string relativeToURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a new URL with the specified local file path. * * If a directory exists at the specified path, a slash is appended if there is * no slash yet. * @@ -189,11 +204,11 @@ * @param path The local file path * @return A new, autoreleased OFURL */ + (instancetype)fileURLWithPath: (OFString *)path; -/*! +/** * @brief Creates a new URL with the specified local file path. * * @param path The local file path * @param isDirectory Whether the path is a directory, in which case a slash is * appened if there is no slash yet @@ -201,19 +216,19 @@ */ + (instancetype)fileURLWithPath: (OFString *)path isDirectory: (bool)isDirectory; #endif -/*! +/** * @brief Initializes an already allocated OFURL with the specified string. * * @param string A string describing a URL * @return An initialized OFURL */ - (instancetype)initWithString: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFURL with the specified string and * relative URL. * * @param string A string describing a URL * @param URL A URL to which the string is relative @@ -221,11 +236,11 @@ */ - (instancetype)initWithString: (OFString *)string relativeToURL: (OFURL *)URL; #ifdef OF_HAVE_FILES -/*! +/** * @brief Initializes an already allocated OFURL with the specified local file * path. * * If a directory exists at the specified path, a slash is appended if there is * no slash yet. @@ -233,11 +248,11 @@ * @param path The local file path * @return An initialized OFURL */ - (instancetype)initFileURLWithPath: (OFString *)path; -/*! +/** * @brief Initializes an already allocated OFURL with the specified local file * path. * * @param path The local file path * @param isDirectory Whether the path is a directory, in which case a slash is @@ -246,11 +261,11 @@ */ - (instancetype)initFileURLWithPath: (OFString *)path isDirectory: (bool)isDirectory; #endif -/*! +/** * @brief Returns a new URL with the specified path component appended. * * If the URL is a file URL, the file system is queried whether the appended * component is a directory. * @@ -259,11 +274,11 @@ * instead. * @return A new URL with the specified path component appended */ - (OFURL *)URLByAppendingPathComponent: (OFString *)component; -/*! +/** * @brief Returns a new URL with the specified path component appended. * * @param component The path component to append. If it starts with the slash, * the component is not appended, but replaces the path * instead. @@ -288,56 +303,66 @@ @property (class, readonly, nonatomic) OFCharacterSet *URLPathAllowedCharacterSet; @property (class, readonly, nonatomic) OFCharacterSet *URLQueryAllowedCharacterSet; @property (class, readonly, nonatomic) + OFCharacterSet *URLQueryKeyValueAllowedCharacterSet; +@property (class, readonly, nonatomic) OFCharacterSet *URLFragmentAllowedCharacterSet; #endif -/*! +/** * @brief Returns the characters allowed in the scheme part of a URL. * * @return The characters allowed in the scheme part of a URL. */ + (OFCharacterSet *)URLSchemeAllowedCharacterSet; -/*! +/** * @brief Returns the characters allowed in the host part of a URL. * * @return The characters allowed in the host part of a URL. */ + (OFCharacterSet *)URLHostAllowedCharacterSet; -/*! +/** * @brief Returns the characters allowed in the user part of a URL. * * @return The characters allowed in the user part of a URL. */ + (OFCharacterSet *)URLUserAllowedCharacterSet; -/*! +/** * @brief Returns the characters allowed in the password part of a URL. * * @return The characters allowed in the password part of a URL. */ + (OFCharacterSet *)URLPasswordAllowedCharacterSet; -/*! +/** * @brief Returns the characters allowed in the path part of a URL. * * @return The characters allowed in the path part of a URL. */ + (OFCharacterSet *)URLPathAllowedCharacterSet; -/*! +/** * @brief Returns the characters allowed in the query part of a URL. * * @return The characters allowed in the query part of a URL. */ + (OFCharacterSet *)URLQueryAllowedCharacterSet; -/*! +/** + * @brief Returns the characters allowed in a key/value in the query part of a + * URL. + * + * @return The characters allowed in a key/value in the query part of a URL. + */ ++ (OFCharacterSet *)URLQueryKeyValueAllowedCharacterSet; + +/** * @brief Returns the characters allowed in the fragment part of a URL. * * @return The characters allowed in the fragment part of a URL. */ + (OFCharacterSet *)URLFragmentAllowedCharacterSet; Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -20,10 +20,11 @@ #include #include #import "OFURL.h" #import "OFArray.h" +#import "OFDictionary.h" #import "OFNumber.h" #import "OFString.h" #import "OFXMLElement.h" #ifdef OF_HAVE_FILES @@ -49,15 +50,19 @@ @interface OFURLPathAllowedCharacterSet: OFURLAllowedCharacterSetBase @end @interface OFURLQueryOrFragmentAllowedCharacterSet: OFURLAllowedCharacterSetBase @end + +@interface OFURLQueryKeyValueAllowedCharacterSet: OFURLAllowedCharacterSetBase +@end static OFCharacterSet *URLAllowedCharacterSet = nil; static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; +static OFCharacterSet *URLQueryKeyValueAllowedCharacterSet = nil; static of_once_t URLAllowedCharacterSetOnce = OF_ONCE_INIT; static of_once_t URLQueryOrFragmentAllowedCharacterSetOnce = OF_ONCE_INIT; static void @@ -84,10 +89,17 @@ initURLQueryOrFragmentAllowedCharacterSet(void) { URLQueryOrFragmentAllowedCharacterSet = [[OFURLQueryOrFragmentAllowedCharacterSet alloc] init]; } + +static void +initURLQueryKeyValueAllowedCharacterSet(void) +{ + URLQueryKeyValueAllowedCharacterSet = + [[OFURLQueryKeyValueAllowedCharacterSet alloc] init]; +} OF_DIRECT_MEMBERS @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; @@ -247,10 +259,41 @@ default: return false; } } @end + +@implementation OFURLQueryKeyValueAllowedCharacterSet +- (bool)characterIsMember: (of_unichar_t)character +{ + if (character < CHAR_MAX && of_ascii_isalnum(character)) + return true; + + switch (character) { + case '-': + case '.': + case '_': + case '~': + case '!': + case '$': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case ':': + case '@': + case '/': + case '?': + return true; + default: + return false; + } +} +@end @implementation OFInvertedCharacterSetWithoutPercent - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @@ -339,10 +382,18 @@ of_once(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } + ++ (OFCharacterSet *)URLQueryKeyValueAllowedCharacterSet +{ + static of_once_t onceControl = OF_ONCE_INIT; + of_once(&onceControl, initURLQueryKeyValueAllowedCharacterSet); + + return URLQueryKeyValueAllowedCharacterSet; +} + (OFCharacterSet *)URLFragmentAllowedCharacterSet { of_once(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); @@ -486,16 +537,16 @@ portString = [OFString stringWithUTF8String: tmp2 length: UTF8String - tmp2]; if (portString.length == 0 || - portString.decimalValue > 65535) + portString.unsignedLongLongValue > 65535) @throw [OFInvalidFormatException exception]; - _port = [[OFNumber alloc] initWithUInt16: - (uint16_t)portString.decimalValue]; + _port = [[OFNumber alloc] initWithUnsignedShort: + portString.unsignedLongLongValue]; } else if (*UTF8String != '\0') @throw [OFInvalidFormatException exception]; isIPv6Host = true; } else if ((tmp2 = strchr(UTF8String, ':')) != NULL) { @@ -507,15 +558,15 @@ _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; portString = [OFString stringWithUTF8String: tmp2]; - if (portString.decimalValue > 65535) + if (portString.unsignedLongLongValue > 65535) @throw [OFInvalidFormatException exception]; - _port = [[OFNumber alloc] initWithUInt16: - (uint16_t)portString.decimalValue]; + _port = [[OFNumber alloc] initWithUnsignedShort: + portString.unsignedLongLongValue]; } else _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; if (!isIPv6Host) @@ -983,10 +1034,41 @@ - (OFString *)URLEncodedQuery { return _URLEncodedQuery; } + +- (OFDictionary OF_GENERIC(OFString *, OFString *) *)queryDictionary +{ + void *pool; + OFArray OF_GENERIC(OFString *) *pairs; + OFMutableDictionary OF_GENERIC(OFString *, OFString *) *ret; + + if (_URLEncodedQuery == nil) + return nil; + + pool = objc_autoreleasePoolPush(); + pairs = [_URLEncodedQuery componentsSeparatedByString: @"&"]; + ret = [OFMutableDictionary dictionaryWithCapacity: pairs.count]; + + for (OFString *pair in pairs) { + OFArray *parts = [pair componentsSeparatedByString: @"="]; + + if (parts.count != 2) + @throw [OFInvalidFormatException exception]; + + [ret setObject: [[parts objectAtIndex: 1] stringByURLDecoding] + forKey: [[parts objectAtIndex: 0] stringByURLDecoding]]; + } + + [ret makeImmutable]; + [ret retain]; + + objc_autoreleasePoolPop(pool); + + return [ret autorelease]; +} - (OFString *)fragment { return _URLEncodedFragment.stringByURLDecoding; } Index: src/OFURLHandler.h ================================================================== --- src/OFURLHandler.h +++ src/OFURLHandler.h @@ -24,27 +24,27 @@ @class OFArray OF_GENERIC(ObjectType); @class OFDate; @class OFStream; @class OFURL; -/*! +/** * @class OFURLHandler OFURLHandler.h ObjFW/OFURLHandler.h * * @brief A handler for a URL scheme. */ @interface OFURLHandler: OFObject { OFString *_scheme; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFURLHandler, 4) } -/*! +/** * @brief The scheme this OFURLHandler handles. */ @property (readonly, nonatomic) OFString *scheme; -/*! +/** * @brief Registers the specified class as the handler for the specified scheme. * * If the same class is specified for two schemes, one instance of it is * created per scheme. * @@ -54,28 +54,28 @@ * same scheme is already registered, registration fails. */ + (bool)registerClass: (Class)class_ forScheme: (OFString *)scheme; -/*! +/** * @brief Returns the handler for the specified URL. * * @return The handler for the specified URL. */ + (nullable OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes the handler for the specified scheme. * * @param scheme The scheme to initialize for * @return An initialized URL handler */ - (instancetype)initWithScheme: (OFString *)scheme OF_DESIGNATED_INITIALIZER; -/*! +/** * @brief Opens the item at the specified URL. * * @param URL The URL of the item which should be opened * @param mode The mode in which the file should be opened.@n * Possible modes are: @@ -95,20 +95,20 @@ * allowed to implement additional, scheme-specific modes. */ - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode; -/*! +/** * @brief Returns the attributes for the item at the specified URL. * * @param URL The URL to return the attributes for * @return A dictionary of attributes for the specified URL, with the keys of * type @ref of_file_attribute_key_t */ - (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL; -/*! +/** * @brief Sets the attributes for the item at the specified URL. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified URL @@ -115,53 +115,53 @@ * @param URL The URL of the item to set the attributes for */ - (void)setAttributes: (of_file_attributes_t)attributes ofItemAtURL: (OFURL *)URL; -/*! +/** * @brief Checks whether a file exists at the specified URL. * * @param URL The URL to check * @return A boolean whether there is a file at the specified URL */ - (bool)fileExistsAtURL: (OFURL *)URL; -/*! +/** * @brief Checks whether a directory exists at the specified URL. * * @param URL The URL to check * @return A boolean whether there is a directory at the specified URL */ - (bool)directoryExistsAtURL: (OFURL *)URL; -/*! +/** * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create */ - (void)createDirectoryAtURL: (OFURL *)URL; -/*! +/** * @brief Returns an array with the items in the specified directory. * * @note `.` and `..` are not part of the returned array. * * @param URL The URL to the directory whose items should be returned * @return An array of OFString with the items in the specified directory */ - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL; -/*! +/** * @brief Removes the item at the specified URL. * * If the item at the specified URL is a directory, it is removed recursively. * * @param URL The URL to the item which should be removed */ - (void)removeItemAtURL: (OFURL *)URL; -/*! +/** * @brief Creates a hard link for the specified item. * * The destination URL must have a full path, which means it must include the * name of the item. * @@ -171,11 +171,11 @@ * @param destination The URL to the item which should link to the source */ - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination; -/*! +/** * @brief Creates a symbolic link for an item. * * The destination uRL must have a full path, which means it must include the * name of the item. * @@ -188,11 +188,11 @@ * @param target The target of the symbolic link */ - (void)createSymbolicLinkAtURL: (OFURL *)URL withDestinationPath: (OFString *)target; -/*! +/** * @brief Tries to efficiently copy an item. If a copy would only be possible * by reading the entire item and then writing it, it returns false. * * The destination URL must have a full path, which means it must include the * name of the item. @@ -208,11 +208,11 @@ * reported via exceptions and not by returning false! */ - (bool)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination; -/*! +/** * @brief Tries to efficiently move an item. If a move would only be possible * by copying the source and deleting it, it returns false. * * The destination URL must have a full path, which means it must include the * name of the item. Index: src/OFURLHandler.m ================================================================== --- src/OFURLHandler.m +++ src/OFURLHandler.m @@ -80,31 +80,35 @@ [handlers setObject: handler forKey: scheme]; } @finally { [handler release]; } - - return true; #ifdef OF_HAVE_THREADS } @finally { [mutex unlock]; } #endif + + return true; } + (OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL { + OF_KINDOF(OFURLHandler *) handler; + #ifdef OF_HAVE_THREADS [mutex lock]; @try { #endif - return [handlers objectForKey: URL.scheme]; + handler = [handlers objectForKey: URL.scheme]; #ifdef OF_HAVE_THREADS } @finally { [mutex unlock]; } #endif + + return handler; } - (instancetype)init { OF_INVALID_INIT_METHOD Index: src/OFValue.h ================================================================== --- src/OFValue.h +++ src/OFValue.h @@ -17,68 +17,68 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFValue OFValue.h ObjFW/OFValue.h * * @brief A class for storing arbitrary values in an object. */ @interface OFValue: OFObject { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFValue, 4) } -/*! +/** * @brief The ObjC type encoding of the value. */ @property (readonly, nonatomic) const char *objCType; -/*! +/** * @brief The value as a pointer to void. * * If the value is not pointer-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) void *pointerValue; -/*! +/** * @brief The value as a non-retained object. * * If the value is not pointer-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) id nonretainedObjectValue; -/*! +/** * @brief The value as a range. * * If the value is not range-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) of_range_t rangeValue; -/*! +/** * @brief The value as a point. * * If the value is not point-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) of_point_t pointValue; -/*! +/** * @brief The value as a dimension. * * If the value is not dimension-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) of_dimension_t dimensionValue; -/*! +/** * @brief The value as a rectangle. * * If the value is not rectangle-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) of_rectangle_t rectangleValue; -/*! +/** * @brief Creates a new, autorelease OFValue with the specified bytes of the * specified type. * * @param bytes The bytes containing the value * @param objCType The ObjC type encoding for the value @@ -85,21 +85,21 @@ * @return A new, autoreleased OFValue */ + (instancetype)valueWithBytes: (const void *)bytes objCType: (const char *)objCType; -/*! +/** * @brief Creates a new, autoreleased OFValue containing the specified pointer. * * Only the raw value of the pointer is stored and no data will be copied. * * @param pointer The pointer the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithPointer: (const void *)pointer; -/*! +/** * @brief Creates a new, autoreleased OFValue containing the specified * non-retained object. * * The object is not retained, which makes this useful for storing objects in * collections without retaining them. @@ -107,45 +107,45 @@ * @param object The object the OFValue should contain without retaining it * @return A new, autoreleased OFValue */ + (instancetype)valueWithNonretainedObject: (id)object; -/*! +/** * @brief Creates a new, autoreleased OFValue containing the specified range. * * @param range The range the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithRange: (of_range_t)range; -/*! +/** * @brief Creates a new, autoreleased OFValue containing the specified point. * * @param point The point the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithPoint: (of_point_t)point; -/*! +/** * @brief Creates a new, autoreleased OFValue containing the specified * dimension. * * @param dimension The dimension the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithDimension: (of_dimension_t)dimension; -/*! +/** * @brief Creates a new, autoreleased OFValue containing the specified * rectangle. * * @param rectangle The rectangle the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithRectangle: (of_rectangle_t)rectangle; -/*! +/** * @brief Initializes an already allocated OFValue with the specified bytes of * the specified type. * * @param bytes The bytes containing the value * @param objCType The ObjC type encoding for the value @@ -152,11 +152,11 @@ * @return An initialized OFValue */ - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType; -/*! +/** * @brief Initializes an already allocated OFValue containing the specified * pointer. * * Only the raw value of the pointer is stored and no data will be copied. * @@ -163,11 +163,11 @@ * @param pointer The pointer the OFValue should contain * @return An initialized OFValue */ - (instancetype)initWithPointer: (const void *)pointer; -/*! +/** * @brief Initializes an already allocated OFValue containing the specified * non-retained object. * * The object is not retained, which makes this useful for storing objects in * collections without retaining them. @@ -175,47 +175,47 @@ * @param object The object the OFValue should contain without retaining it * @return An initialized OFValue */ - (instancetype)initWithNonretainedObject: (id)object; -/*! +/** * @brief Initializes an already allocated OFValue containing the specified * range. * * @param range The range the OFValue should contain * @return An initialized OFValue */ - (instancetype)initWithRange: (of_range_t)range; -/*! +/** * @brief Initializes an already allocated OFValue containing the specified * point. * * @param point The point the OFValue should contain * @return An initialized OFValue */ - (instancetype)initWithPoint: (of_point_t)point; -/*! +/** * @brief Initializes an already allocated OFValue containing the specified * dimension. * * @param dimension The dimension the OFValue should contain * @return An initialized OFValue */ - (instancetype)initWithDimension: (of_dimension_t)dimension; -/*! +/** * @brief Initializes an already allocated OFValue containing the specified * rectangle. * * @param rectangle The rectangle the OFValue should contain * @return An initialized OFValue */ - (instancetype)initWithRectangle: (of_rectangle_t)rectangle; -/*! +/** * @brief Gets the value. * * If the specified size does not match, this raises an * @ref OFOutOfRangeException. * Index: src/OFValue.m ================================================================== --- src/OFValue.m +++ src/OFValue.m @@ -166,10 +166,11 @@ - (bool)isEqual: (id)object { const char *objCType; size_t size; void *value, *otherValue; + bool ret; if (object == self) return true; if (![object isKindOfClass: [OFValue class]]) @@ -196,15 +197,17 @@ [self getValue: value size: size]; [object getValue: otherValue size: size]; - return (memcmp(value, otherValue, size) == 0); + ret = (memcmp(value, otherValue, size) == 0); } @finally { free(value); free(otherValue); } + + return ret; } - (uint32_t)hash { size_t size = of_sizeof_type_encoding(self.objCType); Index: src/OFWindowsRegistryKey.h ================================================================== --- src/OFWindowsRegistryKey.h +++ src/OFWindowsRegistryKey.h @@ -22,11 +22,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; -/*! +/** * @class OFWindowsRegistryKey \ * OFWindowsRegistryKey.h ObjFW/OFWindowsRegistryKey.h */ OF_SUBCLASSING_RESTRICTED @interface OFWindowsRegistryKey: OFObject @@ -33,48 +33,48 @@ { HKEY _hKey; bool _close; } -/*! +/** * @brief Returns the OFWindowsRegistryKey for the HKEY_CLASSES_ROOT key. * * @return The OFWindowsRegistryKey for the HKEY_CLASSES_ROOT key */ + (instancetype)classesRootKey; -/*! +/** * @brief Returns the OFWindowsRegistryKey for the HKEY_CURRENT_CONFIG key. * * @return The OFWindowsRegistryKey for the HKEY_CURRENT_CONFIG key */ + (instancetype)currentConfigKey; -/*! +/** * @brief Returns the OFWindowsRegistryKey for the HKEY_CURRENT_USER key. * * @return The OFWindowsRegistryKey for the HKEY_CURRENT_USER key */ + (instancetype)currentUserKey; -/*! +/** * @brief Returns the OFWindowsRegistryKey for the HKEY_LOCAL_MACHINE key. * * @return The OFWindowsRegistryKey for the HKEY_LOCAL_MACHINE key */ + (instancetype)localMachineKey; -/*! +/** * @brief Returns the OFWindowsRegistryKey for the HKEY_USERS key. * * @return The OFWindowsRegistryKey for the HKEY_USERS key */ + (instancetype)usersKey; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` * documentation for `samDesired` @@ -82,11 +82,11 @@ */ - (nullable OFWindowsRegistryKey *) openSubkeyAtPath: (OFString *)path securityAndAccessRights: (REGSAM)securityAndAccessRights; -/*! +/** * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open * @param options Please refer to the `RegOpenKeyEx()` documentation for * `ulOptions`. Usually 0. @@ -97,11 +97,11 @@ - (nullable OFWindowsRegistryKey *) openSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights; -/*! +/** * @brief Creates a subkey at the specified path or opens it if it already * exists. * * @param path The path of the subkey to create * @param securityAndAccessRights Please refer to the `RegCreateKeyEx()` @@ -109,11 +109,11 @@ * @return The subkey with the specified path */ - (OFWindowsRegistryKey *)createSubkeyAtPath: (OFString *)path securityAndAccessRights: (REGSAM)securityAndAccessRights; -/*! +/** * @brief Creates a subkey at the specified path or opens it if it already * exists. * * @param path The path of the subkey to create * @param options Please refer to the `RegCreateKeyEx()` documentation. @@ -133,21 +133,21 @@ options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (nullable SECURITY_ATTRIBUTES *)securityAttributes disposition: (nullable DWORD *)disposition; -/*! +/** * @brief Returns the data for the specified value at the specified path. * * @param value The name of the value to return * @param type A pointer to store the type of the value, or NULL * @return The data for the specified value */ - (nullable OFData *)dataForValue: (nullable OFString *)value type: (nullable DWORD *)type; -/*! +/** * @brief Sets the data for the specified value. * * @param data The data to set the value to * @param value The name of the value to set * @param type The type for the value @@ -154,38 +154,38 @@ */ - (void)setData: (nullable OFData *)data forValue: (nullable OFString *)value type: (DWORD)type; -/*! +/** * @brief Returns the string for the specified value at the specified path. * * @param value The name of the value to return * @return The string for the specified value */ - (nullable OFString *)stringForValue: (nullable OFString *)value; -/*! +/** * @brief Returns the string for the specified value at the specified path. * * @param value The name of the value to return * @param type A pointer to store the type of the value, or NULL * @return The string for the specified value */ - (nullable OFString *)stringForValue: (nullable OFString *)value type: (nullable DWORD *)type; -/*! +/** * @brief Sets the string for the specified value. * * @param string The string to set the value to * @param value The name of the value to set */ - (void)setString: (nullable OFString *)string forValue: (nullable OFString *)value; -/*! +/** * @brief Sets the string for the specified value. * * @param string The string to set the value to * @param value The name of the value to set * @param type The type for the value @@ -192,21 +192,21 @@ */ - (void)setString: (nullable OFString *)string forValue: (nullable OFString *)value type: (DWORD)type; -/*! +/** * @brief Deletes the specified value. * * @param value The value to delete */ - (void)deleteValue: (nullable OFString *)value; -/*! +/** * @brief Deletes the specified subkey. * * @param subkeyPath The path of the subkey to delete */ - (void)deleteSubkeyAtPath: (OFString *)subkeyPath; @end OF_ASSUME_NONNULL_END Index: src/OFXMLAttribute.h ================================================================== --- src/OFXMLAttribute.h +++ src/OFXMLAttribute.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @class OFXMLAttribute OFXMLAttribute.h ObjFW/OFXMLAttribute.h * * @brief A representation of an attribute of an XML element as an object. */ @interface OFXMLAttribute: OFXMLNode @@ -31,39 +31,39 @@ #if defined(OF_XML_ELEMENT_M) || defined(OF_XML_PARSER_M) @public #endif OFString *_name, *_Nullable _namespace, *_stringValue; bool _useDoubleQuotes; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLAttribute, 4) } -/*! +/** * @brief The name of the attribute. */ @property (readonly, nonatomic) OFString *name; -/*! +/** * @brief The namespace of the attribute. */ #ifndef __cplusplus @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *namespace; #else @property OF_NULLABLE_PROPERTY (readonly, nonatomic, getter=namespace) OFString *namespace_; #endif -/*! +/** * @brief Creates a new XML attribute. * * @param name The name of the attribute * @param stringValue The string value of the attribute * @return A new autoreleased OFXMLAttribute with the specified parameters */ + (instancetype)attributeWithName: (OFString *)name stringValue: (OFString *)stringValue; -/*! +/** * @brief Creates a new XML attribute. * * @param name The name of the attribute * @param namespace_ The namespace of the attribute * @param stringValue The string value of the attribute @@ -71,21 +71,21 @@ */ + (instancetype)attributeWithName: (OFString *)name namespace: (nullable OFString *)namespace_ stringValue: (OFString *)stringValue; -/*! +/** * @brief Initializes an already allocated OFXMLAttribute. * * @param name The name of the attribute * @param stringValue The string value of the attribute * @return An initialized OFXMLAttribute with the specified parameters */ - (instancetype)initWithName: (OFString *)name stringValue: (OFString *)stringValue; -/*! +/** * @brief Initializes an already allocated OFXMLAttribute. * * @param name The name of the attribute * @param namespace_ The namespace of the attribute * @param stringValue The string value of the attribute Index: src/OFXMLCDATA.h ================================================================== --- src/OFXMLCDATA.h +++ src/OFXMLCDATA.h @@ -17,30 +17,30 @@ #import "OFXMLNode.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFXMLCDATA OFXMLCDATA.h ObjFW/OFXMLCDATA.h * * @brief A class representing XML CDATA. */ @interface OFXMLCDATA: OFXMLNode { OFString *_CDATA; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLCDATA, 4) } -/*! +/** * @brief Creates a new OFXMLCDATA with the specified string. * * @param string The string value for the CDATA * @return A new OFXMLCDATA */ + (instancetype)CDATAWithString: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFXMLCDATA with the specified string. * * @param string The string value for the CDATA * @return An initialized OFXMLCDATA */ Index: src/OFXMLCharacters.h ================================================================== --- src/OFXMLCharacters.h +++ src/OFXMLCharacters.h @@ -17,30 +17,30 @@ #import "OFXMLNode.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFXMLCharacters OFXMLCharacters.h ObjFW/OFXMLCharacters.h * * @brief A class representing XML characters. */ @interface OFXMLCharacters: OFXMLNode { OFString *_characters; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLCharacters, 4) } -/*! +/** * @brief Creates a new OFXMLCharacters with the specified string. * * @param string The string value for the characters * @return A new OFXMLCharacters */ + (instancetype)charactersWithString: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFXMLCharacters with the specified * string. * * @param string The string value for the characters * @return An initialized OFXMLCharacters Index: src/OFXMLComment.h ================================================================== --- src/OFXMLComment.h +++ src/OFXMLComment.h @@ -17,30 +17,30 @@ #import "OFXMLNode.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFXMLComment OFXMLComment.h ObjFW/OFXMLComment.h * * @brief A class for representing XML comments. */ @interface OFXMLComment: OFXMLNode { OFString *_comment; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLComment, 4) } -/*! +/** * @brief Creates a new OFXMLComment with the specified string. * * @param string The string for the comment * @return A new OFXMLComment */ + (instancetype)commentWithString: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFXMLComment with the specified * string. * * @param string The string for the comment * @return An initialized OFXMLComment Index: src/OFXMLElement+Serialization.h ================================================================== --- src/OFXMLElement+Serialization.h +++ src/OFXMLElement+Serialization.h @@ -26,13 +26,13 @@ #ifdef __cplusplus } #endif @interface OFXMLElement (OFSerialization) -/*! +/** * @brief The XML element interpreted as serialization and parsed into an * object. */ @property (readonly, nonatomic) id objectByDeserializing; @end OF_ASSUME_NONNULL_END Index: src/OFXMLElement.h ================================================================== --- src/OFXMLElement.h +++ src/OFXMLElement.h @@ -24,11 +24,11 @@ @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableString; @class OFString; @class OFXMLAttribute; -/*! +/** * @class OFXMLElement OFXMLElement.h ObjFW/OFXMLElement.h * * @brief A class which stores an XML element. */ @interface OFXMLElement: OFXMLNode @@ -36,60 +36,60 @@ OFString *_name, *_Nullable _namespace, *_Nullable _defaultNamespace; OFMutableArray OF_GENERIC(OFXMLAttribute *) *_Nullable _attributes; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_Nullable _namespaces; OFMutableArray OF_GENERIC(OFXMLNode *) *_Nullable _children; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLElement, 4) } -/*! +/** * @brief The name of the element. */ @property (copy, nonatomic) OFString *name; -/*! +/** * @brief The namespace of the element. */ #ifndef __cplusplus @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *namespace; #else @property OF_NULLABLE_PROPERTY (copy, nonatomic, getter=namespace, setter=setNamespace:) OFString *namespace_; #endif -/*! +/** * @brief The default namespace for the element to be used if there is no * parent. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *defaultNamespace; -/*! +/** * @brief An array with the attributes of the element. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFArray OF_GENERIC(OFXMLAttribute *) *attributes; -/*! +/** * @brief An array of OFXMLNodes with all children of the element. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFArray OF_GENERIC(OFXMLNode *) *children; -/*! +/** * @brief All children that are elements. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFXMLElement *) *elements; -/*! +/** * @brief Creates a new XML element with the specified name. * * @param name The name for the element * @return A new autoreleased OFXMLElement with the specified element name */ + (instancetype)elementWithName: (OFString *)name; -/*! +/** * @brief Creates a new XML element with the specified name and string value. * * @param name The name for the element * @param stringValue The value for the element * @return A new autoreleased OFXMLElement with the specified element name and @@ -96,11 +96,11 @@ * value */ + (instancetype)elementWithName: (OFString *)name stringValue: (nullable OFString *)stringValue; -/*! +/** * @brief Creates a new XML element with the specified name and namespace. * * @param name The name for the element * @param namespace_ The namespace for the element * @return A new autoreleased OFXMLElement with the specified element name and @@ -107,11 +107,11 @@ * namespace */ + (instancetype)elementWithName: (OFString *)name namespace: (nullable OFString *)namespace_; -/*! +/** * @brief Creates a new XML element with the specified name, namespace and * string value. * * @param name The name for the element * @param namespace_ The namespace for the element @@ -121,29 +121,29 @@ */ + (instancetype)elementWithName: (OFString *)name namespace: (nullable OFString *)namespace_ stringValue: (nullable OFString *)stringValue; -/*! +/** * @brief Creates a new element with the specified element. * * @param element An OFXMLElement to initialize the OFXMLElement with * @return A new autoreleased OFXMLElement with the contents of the specified * element */ + (instancetype)elementWithElement: (OFXMLElement *)element; -/*! +/** * @brief Parses the string and returns an OFXMLElement for it. * * @param string The string to parse * @return A new autoreleased OFXMLElement with the contents of the string */ + (instancetype)elementWithXMLString: (OFString *)string; #ifdef OF_HAVE_FILES -/*! +/** * @brief Parses the specified file and returns an OFXMLElement for it. * * @param path The path to the file * @return A new autoreleased OFXMLElement with the contents of the specified * file @@ -151,19 +151,19 @@ + (instancetype)elementWithFile: (OFString *)path; #endif - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFXMLElement with the specified name. * * @param name The name for the element * @return An initialized OFXMLElement with the specified element name */ - (instancetype)initWithName: (OFString *)name; -/*! +/** * @brief Initializes an already allocated OFXMLElement with the specified name * and string value. * * @param name The name for the element * @param stringValue The value for the element @@ -171,11 +171,11 @@ * value */ - (instancetype)initWithName: (OFString *)name stringValue: (nullable OFString *)stringValue; -/*! +/** * @brief Initializes an already allocated OFXMLElement with the specified name * and namespace. * * @param name The name for the element * @param namespace_ The namespace for the element @@ -183,11 +183,11 @@ * namespace */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)namespace_; -/*! +/** * @brief Initializes an already allocated OFXMLElement with the specified name, * namespace and value. * * @param name The name for the element * @param namespace_ The namespace for the element @@ -197,31 +197,31 @@ */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)namespace_ stringValue: (nullable OFString *)stringValue; -/*! +/** * @brief Initializes an already allocated OFXMLElement with the specified * element. * * @param element An OFXMLElement to initialize the OFXMLElement with * @return A new autoreleased OFXMLElement with the contents of the specified * element */ - (instancetype)initWithElement: (OFXMLElement *)element; -/*! +/** * @brief Parses the string and initializes an already allocated OFXMLElement * with it. * * @param string The string to parse * @return An initialized OFXMLElement with the contents of the string */ - (instancetype)initWithXMLString: (OFString *)string; #ifdef OF_HAVE_FILES -/*! +/** * @brief Parses the specified file and initializes an already allocated * OFXMLElement with it. * * @param path The path to the file * @return An initialized OFXMLElement with the contents of the specified file @@ -229,39 +229,39 @@ - (instancetype)initWithFile: (OFString *)path; #endif - (instancetype)initWithSerialization: (OFXMLElement *)element; -/*! +/** * @brief Sets a prefix for a namespace. * * @param prefix The prefix for the namespace * @param namespace_ The namespace for which the prefix is set */ - (void)setPrefix: (OFString *)prefix forNamespace: (OFString *)namespace_; -/*! +/** * @brief Binds a prefix for a namespace. * * @param prefix The prefix for the namespace * @param namespace_ The namespace for which the prefix is bound */ - (void)bindPrefix: (OFString *)prefix forNamespace: (OFString *)namespace_; -/*! +/** * @brief Adds the specified attribute. * * If an attribute with the same name and namespace already exists, it is not * added. * * @param attribute The attribute to add */ - (void)addAttribute: (OFXMLAttribute *)attribute; -/*! +/** * @brief Adds the specified attribute with the specified string value. * * If an attribute with the same name and namespace already exists, it is not * added. * @@ -269,11 +269,11 @@ * @param stringValue The value of the attribute */ - (void)addAttributeWithName: (OFString *)name stringValue: (OFString *)stringValue; -/*! +/** * @brief Adds the specified attribute with the specified namespace and string * value. * * If an attribute with the same name and namespace already exists, it is not * added. @@ -284,138 +284,138 @@ */ - (void)addAttributeWithName: (OFString *)name namespace: (nullable OFString *)namespace_ stringValue: (OFString *)stringValue; -/*! +/** * @brief Returns the attribute with the specified name. * * @param attributeName The name of the attribute * @return The attribute with the specified name */ - (nullable OFXMLAttribute *)attributeForName: (OFString *)attributeName; -/*! +/** * @brief Returns the attribute with the specified name and namespace. * * @param attributeName The name of the attribute * @param attributeNS The namespace of the attribute * @return The attribute with the specified name and namespace */ - (nullable OFXMLAttribute *)attributeForName: (OFString *)attributeName namespace: (nullable OFString *)attributeNS; -/*! +/** * @brief Removes the attribute with the specified name. * * @param attributeName The name of the attribute */ - (void)removeAttributeForName: (OFString *)attributeName; -/*! +/** * @brief Removes the attribute with the specified name and namespace. * * @param attributeName The name of the attribute * @param attributeNS The namespace of the attribute */ - (void)removeAttributeForName: (OFString *)attributeName namespace: (nullable OFString *)attributeNS; -/*! +/** * @brief Adds a child to the OFXMLElement. * * @param child An OFXMLNode which is added as a child */ - (void)addChild: (OFXMLNode *)child; -/*! +/** * @brief Inserts a child at the specified index. * * @param child An OFXMLNode which is added as a child * @param index The index where the child is added */ - (void)insertChild: (OFXMLNode *)child atIndex: (size_t)index; -/*! +/** * @brief Inserts the specified children at the specified index. * * @param children An array of OFXMLNodes which are added as children * @param index The index where the child is added */ - (void)insertChildren: (OFArray OF_GENERIC(OFXMLNode *) *)children atIndex: (size_t)index; -/*! +/** * @brief Removes the first child that is equal to the specified OFXMLNode. * * @param child The child to remove from the OFXMLElement */ - (void)removeChild: (OFXMLNode *)child; -/*! +/** * @brief Removes the child at the specified index. * * @param index The index of the child to remove */ - (void)removeChildAtIndex: (size_t)index; -/*! +/** * @brief Replaces the first child that is equal to the specified OFXMLNode * with the specified node. * * @param child The child to replace * @param node The node to replace the child with */ - (void)replaceChild: (OFXMLNode *)child withNode: (OFXMLNode *)node; -/*! +/** * @brief Replaces the child at the specified index with the specified node. * * @param index The index of the child to replace * @param node The node to replace the child with */ - (void)replaceChildAtIndex: (size_t)index withNode: (OFXMLNode *)node; -/*! +/** * @brief Returns all children that have the specified namespace. * * @return All children that have the specified namespace */ - (OFArray OF_GENERIC(OFXMLElement *) *)elementsForNamespace: (nullable OFString *)elementNS; -/*! +/** * @brief Returns the first child element with the specified name. * * @param elementName The name of the element * @return The first child element with the specified name */ - (nullable OFXMLElement *)elementForName: (OFString *)elementName; -/*! +/** * @brief Returns the child elements with the specified name. * * @param elementName The name of the elements * @return The child elements with the specified name */ - (OFArray OF_GENERIC(OFXMLElement *) *)elementsForName: (OFString *)elementName; -/*! +/** * @brief Returns the first child element with the specified name and namespace. * * @param elementName The name of the element * @param elementNS The namespace of the element * @return The first child element with the specified name and namespace */ - (nullable OFXMLElement *)elementForName: (OFString *)elementName namespace: (nullable OFString *)elementNS; -/*! +/** * @brief Returns the child elements with the specified name and namespace. * * @param elementName The name of the elements * @param elementNS The namespace of the elements * @return The child elements with the specified name and namespace Index: src/OFXMLElementBuilder.h ================================================================== --- src/OFXMLElementBuilder.h +++ src/OFXMLElementBuilder.h @@ -22,19 +22,19 @@ @class OFMutableArray OF_GENERIC(ObjectType); @class OFXMLElement; @class OFXMLElementBuilder; -/*! +/** * @protocol OFXMLElementBuilderDelegate * OFXMLElementBuilder.h ObjFW/OFXMLElementBuilder.h * * @brief A protocol that needs to be implemented by delegates for * OFXMLElementBuilder. */ @protocol OFXMLElementBuilderDelegate -/*! +/** * @brief This callback is called when the OFXMLElementBuilder built an element. * * If the OFXMLElementBuilder was used as a delegate for the OFXMLParser since * parsing started, this will return the complete document as an OFXMLElement * with all children. @@ -44,11 +44,11 @@ */ - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildElement: (OFXMLElement *)element; @optional -/*! +/** * @brief This callback is called when the OFXMLElementBuilder built an * OFXMLNode which is not inside an element. * * This is usually called for comments or whitespace character data before the * root element. @@ -57,11 +57,11 @@ * @param node The OFXMLNode the OFXMLElementBuilder built */ - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildParentlessNode: (OFXMLNode *)node; -/*! +/** * @brief This callback is called when the OFXMLElementBuilder gets a close tag * which does not belong there. * * Most likely, the OFXMLElementBuilder was used to build XML only of a child * of the root element and the root element was closed. Often the delegate is @@ -80,11 +80,11 @@ - (void)elementBuilder: (OFXMLElementBuilder *)builder didNotExpectCloseTag: (OFString *)name prefix: (nullable OFString *)prefix namespace: (nullable OFString *)namespace_; -/*! +/** * @brief This callback is called when the XML parser for the element builder * found an unknown entity. * * @param builder The element builder which found an unknown entity * @param entity The name of the entity @@ -92,11 +92,11 @@ */ - (OFString *)elementBuilder: (OFXMLElementBuilder *)builder foundUnknownEntityNamed: (OFString *)entity; @end -/*! +/** * @class OFXMLElementBuilder OFXMLElementBuilder.h ObjFW/OFXMLElementBuilder.h * * @brief A class implementing the OFXMLParserDelegate protocol that can build * OFXMLElements from the document parsed by the OFXMLParser. * @@ -106,23 +106,23 @@ */ @interface OFXMLElementBuilder: OFObject { OFMutableArray OF_GENERIC(OFXMLElement *) *_stack; id _Nullable _delegate; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLElementBuilder, 4) } -/*! +/** * @brief The delegate for the OFXMLElementBuilder. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief Creates a new element builder. * * @return A new, autoreleased OFXMLElementBuilder */ + (instancetype)elementBuilder; @end OF_ASSUME_NONNULL_END Index: src/OFXMLNode.h ================================================================== --- src/OFXMLNode.h +++ src/OFXMLNode.h @@ -20,67 +20,67 @@ OF_ASSUME_NONNULL_BEGIN @class OFXMLElement; -/*! +/** * @class OFXMLNode OFXMLNode.h ObjFW/OFXMLNode.h * * @brief A class which stores an XML element. */ @interface OFXMLNode: OFObject { - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLNode, 4) } -/*! +/** * @brief The contents of the node as a string value. * * For an @ref OFXMLElement, setting it removes all children and creates a * single child with the specified string value. */ @property (nonatomic, copy) OFString *stringValue; -/*! - * @brief The contents of the receiver as a decimal value. - */ -@property (readonly, nonatomic) intmax_t decimalValue; - -/*! - * @brief The contents of the receiver as a hexadecimal value. - */ -@property (readonly, nonatomic) uintmax_t hexadecimalValue; - -/*! +/** + * @brief The contents of the receiver as a `long long` value. + */ +@property (readonly, nonatomic) long long longLongValue; + +/** + * @brief The contents of the receiver as an `unsigned long long` value. + */ +@property (readonly, nonatomic) unsigned long long unsignedLongLongValue; + +/** * @brief The contents of the receiver as a float value. */ @property (readonly, nonatomic) float floatValue; -/*! +/** * @brief The contents of the receiver as a double value. */ @property (readonly, nonatomic) double doubleValue; -/*! +/** * @brief A string representing the node as an XML string. */ @property (readonly, nonatomic) OFString *XMLString; - (instancetype)init OF_UNAVAILABLE; - (instancetype)initWithSerialization: (OFXMLElement *)element OF_UNAVAILABLE; -/*! +/** * @brief Returns an OFString representing the OFXMLNode as an XML string with * indentation. * * @param indentation The indentation for the XML string * @return An OFString representing the OFXMLNode as an XML string with * indentation */ - (OFString *)XMLStringWithIndentation: (unsigned int)indentation; -/*! +/** * @brief Returns an OFString representing the OFXMLNode as an XML string with * indentation for the specified level. * * @param indentation The indentation for the XML string * @param level The level of indentation @@ -87,8 +87,34 @@ * @return An OFString representing the OFXMLNode as an XML string with * indentation */ - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level; + +/** + * @brief The contents of the receiver as a `long long` value in the specified + * base. + * + * @param base The base to use. If the base is 0, base 16 is assumed if the + * string starts with 0x (after stripping white spaces). If the + * string starts with 0, base 8 is assumed. Otherwise, base 10 is + * assumed. + * @return The contents of the receiver as a `long long` value in the specified + * base + */ +- (long long)longLongValueWithBase: (int)base; + +/** + * @brief The contents of the receiver as an `unsigned long long` value in the + * specified base. + * + * @param base The base to use. If the base is 0, base 16 is assumed if the + * string starts with 0x (after stripping white spaces). If the + * string starts with 0, base 8 is assumed. Otherwise, base 10 is + * assumed. + * @return The contents of the receiver as an `unsigned long long` value in the + * specified base + */ +- (unsigned long long)unsignedLongLongValueWithBase: (int)base; @end OF_ASSUME_NONNULL_END Index: src/OFXMLNode.m ================================================================== --- src/OFXMLNode.m +++ src/OFXMLNode.m @@ -44,18 +44,28 @@ - (void)setStringValue: (OFString *)stringValue { OF_UNRECOGNIZED_SELECTOR } -- (intmax_t)decimalValue +- (long long)longLongValue +{ + return self.stringValue.longLongValue; +} + +- (long long)longLongValueWithBase: (int)base +{ + return [self.stringValue longLongValueWithBase: base]; +} + +- (unsigned long long)unsignedLongLongValue { - return self.stringValue.decimalValue; + return self.stringValue.unsignedLongLongValue; } -- (uintmax_t)hexadecimalValue +- (unsigned long long)unsignedLongLongValueWithBase: (int)base { - return self.stringValue.hexadecimalValue; + return [self.stringValue unsignedLongLongValueWithBase: base]; } - (float)floatValue { return self.stringValue.floatValue; Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -26,28 +26,28 @@ @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFStream; @class OFXMLParser; -/*! +/** * @protocol OFXMLParserDelegate OFXMLParser.h ObjFW/OFXMLParser.h * * @brief A protocol that needs to be implemented by delegates for OFXMLParser. */ @protocol OFXMLParserDelegate @optional -/*! +/** * @brief This callback is called when the XML parser found processing * instructions. * * @param parser The parser which found processing instructions * @param processingInstructions The processing instructions */ - (void)parser: (OFXMLParser *)parser foundProcessingInstructions: (OFString *)processingInstructions; -/*! +/** * @brief This callback is called when the XML parser found the start of a new * tag. * * @param parser The parser which found a new tag * @param name The name of the tag which just started @@ -60,11 +60,11 @@ didStartElement: (OFString *)name prefix: (nullable OFString *)prefix namespace: (nullable OFString *)ns attributes: (nullable OFArray OF_GENERIC(OFXMLAttribute *) *)attributes; -/*! +/** * @brief This callback is called when the XML parser found the end of a tag. * * @param parser The parser which found the end of a tag * @param name The name of the tag which just ended * @param prefix The prefix of the tag which just ended or `nil` @@ -73,11 +73,11 @@ - (void)parser: (OFXMLParser *)parser didEndElement: (OFString *)name prefix: (nullable OFString *)prefix namespace: (nullable OFString *)ns; -/*! +/** * @brief This callback is called when the XML parser found characters. * * In case there are comments or CDATA, it is possible that this callback is * called multiple times in a row. * @@ -85,29 +85,29 @@ * @param characters The characters the XML parser found */ - (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)characters; -/*! +/** * @brief This callback is called when the XML parser found CDATA. * * @param parser The parser which found a string * @param CDATA The CDATA the XML parser found */ - (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA; -/*! +/** * @brief This callback is called when the XML parser found a comment. * * @param parser The parser which found a comment * @param comment The comment the XML parser found */ - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment; -/*! +/** * @brief This callback is called when the XML parser found an entity it * doesn't know. * * The callback is supposed to return a substitution for the entity or `nil` if * it is not known to the callback as well, in which case an exception will be @@ -119,11 +119,11 @@ */ - (nullable OFString *)parser: (OFXMLParser *)parser foundUnknownEntityNamed: (OFString *)entity; @end -/*! +/** * @class OFXMLParser OFXMLParser.h ObjFW/OFXMLParser.h * * @brief An event-based XML parser. * * OFXMLParser is an event-based XML parser which calls the delegate's callbacks @@ -172,71 +172,71 @@ bool _lastCarriageReturn, _finishedParsing; of_string_encoding_t _encoding; size_t _depthLimit; } -/*! +/** * @brief The delegate that is used by the XML parser. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id delegate; -/*! +/** * @brief The current line number. */ @property (readonly, nonatomic) size_t lineNumber; -/*! +/** * @brief Whether the XML parser has finished parsing. */ @property (readonly, nonatomic) bool hasFinishedParsing; -/*! +/** * @brief The depth limit for the XML parser. * * If the depth limit is exceeded, an OFMalformedXMLException is thrown. * * The default is 32. 0 means unlimited (insecure!). */ @property (nonatomic) size_t depthLimit; -/*! +/** * @brief Creates a new XML parser. * * @return A new, autoreleased OFXMLParser */ + (instancetype)parser; -/*! +/** * @brief Parses the specified buffer with the specified size. * * @param buffer The buffer to parse * @param length The length of the buffer */ - (void)parseBuffer: (const char *)buffer length: (size_t)length; -/*! +/** * @brief Parses the specified string. * * @param string The string to parse */ - (void)parseString: (OFString *)string; -/*! +/** * @brief Parses the specified stream. * * @param stream The stream to parse */ - (void)parseStream: (OFStream *)stream; #ifdef OF_HAVE_FILES -/*! +/** * @brief Parses the specified file. * * @param path The path to the file to parse */ - (void)parseFile: (OFString *)path; #endif @end OF_ASSUME_NONNULL_END Index: src/OFXMLProcessingInstructions.h ================================================================== --- src/OFXMLProcessingInstructions.h +++ src/OFXMLProcessingInstructions.h @@ -17,31 +17,31 @@ #import "OFXMLNode.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFXMLProcessingInstructions \ * OFXMLProcessingInstructions.h ObjFW/OFXMLProcessingInstructions.h * * @brief A class for representing XML processing instructions. */ @interface OFXMLProcessingInstructions: OFXMLNode { OFString *_processingInstructions; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFXMLProcessingInstructions, 4) } -/*! +/** * @brief Creates a new OFXMLProcessingInstructions with the specified string. * * @param string The string for the processing instructions * @return A new OFXMLProcessingInstructions */ + (instancetype)processingInstructionsWithString: (OFString *)string; -/*! +/** * @brief Initializes an already allocated OFXMLProcessingInstructions with the * specified string. * * @param string The string for the processing instructions * @return An initialized OFXMLProcessingInstructions Index: src/OFZIPArchive.h ================================================================== --- src/OFZIPArchive.h +++ src/OFZIPArchive.h @@ -24,11 +24,11 @@ @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFStream; -/*! +/** * @class OFZIPArchive OFZIPArchive.h ObjFW/OFZIPArchive.h * * @brief A class for accessing and manipulating ZIP files. */ OF_SUBCLASSING_RESTRICTED @@ -50,16 +50,16 @@ OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *) *_pathToEntryMap; OFStream *_Nullable _lastReturnedStream; } -/*! +/** * @brief The archive comment. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *archiveComment; -/*! +/** * @brief The entries in the central directory of the archive as an array of * objects of class @ref OFZIPArchiveEntry. * * The objects of the array have the same order as the entries in the central * directory, which does not need to be the order in which the actual files are @@ -66,11 +66,11 @@ * stored. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFZIPArchiveEntry *) *entries; -/*! +/** * @brief Creates a new OFZIPArchive object with the specified stream. * * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, @@ -80,11 +80,11 @@ */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES -/*! +/** * @brief Creates a new OFZIPArchive object with the specified file. * * @param path The path to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing @@ -95,11 +95,11 @@ mode: (OFString *)mode; #endif - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFZIPArchive object with the * specified stream. * * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. @@ -110,11 +110,11 @@ */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES -/*! +/** * @brief Initializes an already allocated OFZIPArchive object with the * specified file. * * @param path The path to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, @@ -124,14 +124,17 @@ */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; #endif -/*! +/** * @brief Returns a stream for reading the specified file from the archive. * * @note This method is only available in read mode. + * + * @note The returned stream conforms to @ref OFReadyForReadingObserving if the + * underlying stream does so, too. * * @warning Calling @ref streamForReadingFile: will invalidate all streams * previously returned by @ref streamForReadingFile: or * @ref streamForWritingEntry:! Reading from or writing to an * invalidated stream will throw an @ref OFReadFailedException or @@ -140,14 +143,17 @@ * @param path The path to the file inside the archive * @return A stream for reading the specified file form the archive */ - (OFStream *)streamForReadingFile: (OFString *)path; -/*! +/** * @brief Returns a stream for writing the specified entry to the archive. * * @note This method is only available in write and append mode. + * + * @note The returned stream conforms to @ref OFReadyForWritingObserving if the + * underlying stream does so, too. * * @warning Calling @ref streamForWritingEntry: will invalidate all streams * previously returned by @ref streamForReadingFile: or * @ref streamForWritingEntry:! Reading from or writing to an * invalidated stream will throw an @ref OFReadFailedException or @@ -163,12 +169,12 @@ * * Bit 3 and 11 of the general purpose bit flag. * @return A stream for writing the specified entry to the archive */ - (OFStream *)streamForWritingEntry: (OFZIPArchiveEntry *)entry; -/*! +/** * @brief Closes the OFZIPArchive. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFZIPArchiveEntry.h ================================================================== --- src/OFZIPArchiveEntry.h +++ src/OFZIPArchiveEntry.h @@ -17,11 +17,11 @@ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ enum { OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE = 0, OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_SHRINK = 1, OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_REDUCE_FACTOR_1 = 2, @@ -35,53 +35,53 @@ OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_LZMA = 14, OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_WAVPACK = 97, OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_PPMD = 98 }; -/*! +/** * @brief Attribute compatibility part of ZIP versions. */ enum of_zip_archive_entry_attribute_compatibility { - /*! MS-DOS and OS/2 */ + /** MS-DOS and OS/2 */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MSDOS = 0, - /*! Amiga */ + /** Amiga */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_AMIGA = 1, - /*! OpenVMS */ + /** OpenVMS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OPENVMS = 2, - /*! UNIX */ + /** UNIX */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX = 3, - /*! VM/CMS */ + /** VM/CMS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VM_CMS = 4, - /*! Atari ST */ + /** Atari ST */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ATARI_ST = 5, - /*! OS/2 HPFS */ + /** OS/2 HPFS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS2_HPFS = 6, - /*! Macintosh */ + /** Macintosh */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MACINTOSH = 7, - /*! Z-System */ + /** Z-System */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_Z_SYSTEM = 8, - /*! CP/M */ + /** CP/M */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_CP_M = 9, - /*! Windows NTFS */ + /** Windows NTFS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_WINDOWS_NTFS = 10, - /*! MVS (OS/390 - Z/OS) */ + /** MVS (OS/390 - Z/OS) */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MVS = 11, - /*! VSE */ + /** VSE */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VSE = 12, - /*! Acorn RISC OS */ + /** Acorn RISC OS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ACORN_RISC_OS = 13, - /*! VFAT */ + /** VFAT */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VFAT = 14, - /*! Alternate MVS */ + /** Alternate MVS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ALTERNATE_MVS = 15, - /*! BeOS */ + /** BeOS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_BEOS = 16, - /*! Tandem */ + /** Tandem */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_TANDEM = 17, - /*! OS/400 */ + /** OS/400 */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS_400 = 18, - /*! OS X (Darwin) */ + /** OS X (Darwin) */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS_X = 19 }; enum { OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64 = 0x0001 @@ -90,11 +90,11 @@ @class OFString; @class OFData; @class OFFile; @class OFDate; -/*! +/** * @class OFZIPArchiveEntry OFZIPArchiveEntry.h ObjFW/OFZIPArchiveEntry.h * * @brief A class which represents an entry in the central directory of a ZIP * archive. */ @@ -110,57 +110,57 @@ OFString *_Nullable _fileComment; uint32_t _startDiskNumber; uint16_t _internalAttributes; uint32_t _versionSpecificAttributes; int64_t _localFileHeaderOffset; - OF_RESERVE_IVARS(4) + OF_RESERVE_IVARS(OFZIPArchiveEntry, 4) } -/*! +/** * @brief The file name of the entry. */ @property (readonly, copy, nonatomic) OFString *fileName; -/*! +/** * @brief The comment of the entry's file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *fileComment; -/*! +/** * @brief The extra field of the entry. * * The item size *must* be 1! */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFData *extraField; -/*! +/** * @brief The version which made the entry. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref of_zip_archive_entry_attribute_compatibility. */ @property (readonly, nonatomic) uint16_t versionMadeBy; -/*! +/** * @brief The minimum version required to extract the file. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref of_zip_archive_entry_attribute_compatibility. */ @property (readonly, nonatomic) uint16_t minVersionNeeded; -/*! +/** * @brief The last modification date of the entry's file. * * @note Due to limitations of the ZIP format, this has only 2 second precision. */ @property (readonly, retain, nonatomic) OFDate *modificationDate; -/*! +/** * @brief The compression method of the entry. * * Supported values are: * Value | Description * --------------------------------------------------|--------------- @@ -170,51 +170,51 @@ * * Other values may be returned, but the file cannot be extracted then. */ @property (readonly, nonatomic) uint16_t compressionMethod; -/*! +/** * @brief The compressed size of the entry's file. */ @property (readonly, nonatomic) uint64_t compressedSize; -/*! +/** * @brief The uncompressed size of the entry's file. */ @property (readonly, nonatomic) uint64_t uncompressedSize; -/*! +/** * @brief The CRC32 checksum of the entry's file. */ @property (readonly, nonatomic) uint32_t CRC32; -/*! +/** * @brief The version specific attributes. * * The meaning of the version specific attributes depends on the attribute * compatibility part of the version that made the entry. */ @property (readonly, nonatomic) uint32_t versionSpecificAttributes; -/*! +/** * @brief The general purpose bit flag of the entry. * * See the ZIP specification for details. */ @property (readonly, nonatomic) uint16_t generalPurposeBitFlag; -/*! +/** * @brief Creates a new OFZIPArchiveEntry with the specified file name. * * @param fileName The file name for the OFZIPArchiveEntry * @return A new, autoreleased OFZIPArchiveEntry */ + (instancetype)entryWithFileName: (OFString *)fileName; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated OFZIPArchiveEntry with the specified * file name. * * @param fileName The file name for the OFZIPArchiveEntry * @return An initialized OFZIPArchiveEntry @@ -223,29 +223,29 @@ @end #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief Converts the ZIP entry version to a string. * * @param version The ZIP entry version to convert to a string * @return The ZIP entry version as a string */ extern OFString *of_zip_archive_entry_version_to_string(uint16_t version); -/*! +/** * @brief Convers the ZIP entry compression method to a string. * * @param compressionMethod The ZIP entry compression method to convert to a * string * @return The ZIP entry compression method as a string */ extern OFString *of_zip_archive_entry_compression_method_to_string( uint16_t compressionMethod); -/*! +/** * @brief Gets a pointer to and the size of the extensible data field with the * specified tag. * * @param extraField The extra field to search for an extensible data field with * the specified tag Index: src/bridge/Info.plist.in ================================================================== --- src/bridge/Info.plist.in +++ src/bridge/Info.plist.in @@ -5,11 +5,11 @@ CFBundleExecutable ObjFWBridge CFBundleName ObjFWBridge CFBundleIdentifier - zone.heap.objfw.bridge + im.nil.objfw.bridge CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType FMWK CFBundleVersion Index: src/bridge/NSArray+OFObject.h ================================================================== --- src/bridge/NSArray+OFObject.h +++ src/bridge/NSArray+OFObject.h @@ -29,11 +29,11 @@ extern int _NSArray_OFObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category NSArray (OFObject) \ * NSArray+OFObject.h ObjFWBridge/NSArray+OFObject.h * * @brief Support for bridging NSArrays to OFArrays. */ Index: src/bridge/NSArray+OFObject.m ================================================================== --- src/bridge/NSArray+OFObject.m +++ src/bridge/NSArray+OFObject.m @@ -19,10 +19,10 @@ #import "OFNSArray.h" int _NSArray_OFObject_reference; @implementation NSArray (OFObject) -- (id)OFObject +- (OFArray *)OFObject { return [[[OFNSArray alloc] initWithNSArray: self] autorelease]; } @end Index: src/bridge/NSBridging.h ================================================================== --- src/bridge/NSBridging.h +++ src/bridge/NSBridging.h @@ -25,22 +25,22 @@ # endif #endif OF_ASSUME_NONNULL_BEGIN -/*! +/** * @protocol NSBridging NSBridging.h ObjFWBridge/NSBridging.h * * @brief A protocol implemented by classes supporting bridging Foundation * objects to ObjFW objects. */ @protocol NSBridging -/*! +/** * @brief An instance of an ObjFW object corresponding to the object. * * If possible, the original object is wrapped. If this is not possible, an * autoreleased copy is created. */ @property (readonly, nonatomic) id OFObject; @end OF_ASSUME_NONNULL_END Index: src/bridge/NSDictionary+OFObject.h ================================================================== --- src/bridge/NSDictionary+OFObject.h +++ src/bridge/NSDictionary+OFObject.h @@ -29,11 +29,11 @@ extern int _NSDictionary_OFObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category NSDictionary (OFObject) \ * NSDictionary+OFObject.h ObjFWBridge/NSDictionary+OFObject.h * * @brief Support for bridging NSDictionaries to OFDictionaries. */ Index: src/bridge/NSDictionary+OFObject.m ================================================================== --- src/bridge/NSDictionary+OFObject.m +++ src/bridge/NSDictionary+OFObject.m @@ -19,11 +19,11 @@ #import "OFNSDictionary.h" int _NSDictionary_OFObject_reference; @implementation NSDictionary (OFObject) -- (id)OFObject +- (OFDictionary *)OFObject { return [[[OFNSDictionary alloc] initWithNSDictionary: self] autorelease]; } @end Index: src/bridge/NSEnumerator+OFObject.h ================================================================== --- src/bridge/NSEnumerator+OFObject.h +++ src/bridge/NSEnumerator+OFObject.h @@ -29,11 +29,11 @@ extern int _NSEnumerator_OFObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category NSEnumerator (OFObject) \ * NSEnumerator+OFObject.h ObjFWBridge/NSEnumerator+OFObject.h * * @brief Support for bridging NSEnumerators to OFEnumerators. */ Index: src/bridge/NSEnumerator+OFObject.m ================================================================== --- src/bridge/NSEnumerator+OFObject.m +++ src/bridge/NSEnumerator+OFObject.m @@ -19,11 +19,11 @@ #import "OFNSEnumerator.h" int _NSEnumerator_OFObject_reference; @implementation NSEnumerator (OFObject) -- (id)OFObject +- (OFEnumerator *)OFObject { return [[[OFNSEnumerator alloc] initWithNSEnumerator: self] autorelease]; } @end Index: src/bridge/NSNumber+OFObject.h ================================================================== --- src/bridge/NSNumber+OFObject.h +++ src/bridge/NSNumber+OFObject.h @@ -29,11 +29,11 @@ extern int _NSNumber_OFObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category NSNumber (OFObject) * NSNumber+OFObject.h ObjFWBridge/NSNumber+OFObject.h * * @brief Support for bridging NSNumbers to OFNumbers. */ Index: src/bridge/NSNumber+OFObject.m ================================================================== --- src/bridge/NSNumber+OFObject.m +++ src/bridge/NSNumber+OFObject.m @@ -21,11 +21,11 @@ #import "OFInvalidArgumentException.h" int _NSNumber_OFObject_reference; @implementation NSNumber (OFObject) -- (id)OFObject +- (OFNumber *)OFObject { const char *type = self.objCType; if (strcmp(type, "c") == 0) return [OFNumber numberWithChar: self.charValue]; Index: src/bridge/NSSet+OFObject.h ================================================================== --- src/bridge/NSSet+OFObject.h +++ src/bridge/NSSet+OFObject.h @@ -29,11 +29,11 @@ extern int _NSSet_OFObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category NSSet (OFObject) * NSSet+OFObject.h ObjFWBridge/NSSet+OFObject.h * * @brief Support for bridging NSSets to OFSets. */ Index: src/bridge/NSSet+OFObject.m ================================================================== --- src/bridge/NSSet+OFObject.m +++ src/bridge/NSSet+OFObject.m @@ -19,10 +19,10 @@ #import "OFNSSet.h" int _NSSet_OFObject_reference; @implementation NSSet (OFObject) -- (id)OFObject +- (OFSet *)OFObject { return [[[OFNSSet alloc] initWithNSSet: self] autorelease]; } @end Index: src/bridge/NSString+OFObject.h ================================================================== --- src/bridge/NSString+OFObject.h +++ src/bridge/NSString+OFObject.h @@ -29,11 +29,11 @@ extern int _NSString_OFObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category NSString (OFObject) * NSString+OFObject.h ObjFWBridge/NSString+OFObject.h * * @brief Support for bridging NSStrings to OFStrings. * Index: src/bridge/NSString+OFObject.m ================================================================== --- src/bridge/NSString+OFObject.m +++ src/bridge/NSString+OFObject.m @@ -19,10 +19,10 @@ #import "OFString.h" int _NSString_OFObject_reference; @implementation NSString (OFObject) -- (id)OFObject +- (OFString *)OFObject { return [OFString stringWithUTF8String: self.UTF8String]; } @end Index: src/bridge/OFArray+NSObject.h ================================================================== --- src/bridge/OFArray+NSObject.h +++ src/bridge/OFArray+NSObject.h @@ -35,15 +35,15 @@ extern int _OFArray_NSObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category OFArray (NSObject) \ * OFArray+NSObject.h ObjFWBridge/OFArray+NSObject.h * @brief Support for bridging OFArrays to NSArrays. */ @interface OFArray (NSObject) @property (readonly, nonatomic) NSArray *NSObject; @end OF_ASSUME_NONNULL_END Index: src/bridge/OFArray+NSObject.m ================================================================== --- src/bridge/OFArray+NSObject.m +++ src/bridge/OFArray+NSObject.m @@ -20,10 +20,10 @@ #import "OFArray+NSObject.h" int _OFArray_NSObject_reference; @implementation OFArray (NSObject) -- (id)NSObject +- (NSArray *)NSObject { return [[[NSOFArray alloc] initWithOFArray: self] autorelease]; } @end Index: src/bridge/OFBridging.h ================================================================== --- src/bridge/OFBridging.h +++ src/bridge/OFBridging.h @@ -25,22 +25,22 @@ # endif #endif OF_ASSUME_NONNULL_BEGIN -/*! +/** * @protocol OFBridging OFBridging.h ObjFWBridge/OFBridging.h * * @brief A protocol implemented by classes supporting bridging ObjFW objects * to Foundation objects. */ @protocol OFBridging -/*! +/** * @brief An instance of a Foundation object corresponding to the object. * * If possible, the original object is wrapped. If this is not possible, an * autoreleased copy is created. */ @property (readonly, nonatomic) id NSObject; @end OF_ASSUME_NONNULL_END Index: src/bridge/OFDictionary+NSObject.h ================================================================== --- src/bridge/OFDictionary+NSObject.h +++ src/bridge/OFDictionary+NSObject.h @@ -35,11 +35,11 @@ extern int _OFDictionary_NSObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category OFDictionary (NSObject) \ * OFDictionary+NSObject.h ObjFWBridge/OFDictionary+NSObject.h * * @brief Support for bridging OFDictionaries to NSDictionaries. */ Index: src/bridge/OFDictionary+NSObject.m ================================================================== --- src/bridge/OFDictionary+NSObject.m +++ src/bridge/OFDictionary+NSObject.m @@ -20,11 +20,11 @@ #import "OFDictionary+NSObject.h" int _OFDictionary_NSObject_reference; @implementation OFDictionary (NSObject) -- (id)NSObject +- (NSDictionary *)NSObject { return [[[NSOFDictionary alloc] initWithOFDictionary: self] autorelease]; } @end Index: src/bridge/OFEnumerator+NSObject.h ================================================================== --- src/bridge/OFEnumerator+NSObject.h +++ src/bridge/OFEnumerator+NSObject.h @@ -35,15 +35,15 @@ extern int _OFEnumerator_NSObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category OFEnumerator (NSObject) \ * OFEnumerator+NSObject.h ObjFWBridge/OFEnumerator+NSObject.h * @brief Support for bridging OFEnumerators to NSEnumerators. */ @interface OFEnumerator (NSObject) @property (readonly, nonatomic) NSEnumerator *NSObject; @end OF_ASSUME_NONNULL_END Index: src/bridge/OFEnumerator+NSObject.m ================================================================== --- src/bridge/OFEnumerator+NSObject.m +++ src/bridge/OFEnumerator+NSObject.m @@ -20,11 +20,11 @@ #import "OFEnumerator+NSObject.h" int _OFEnumerator_NSObject_reference; @implementation OFEnumerator (NSObject) -- (id)NSObject +- (NSEnumerator *)NSObject { return [[[NSOFEnumerator alloc] initWithOFEnumerator: self] autorelease]; } @end Index: src/bridge/OFException+Swift.h ================================================================== --- src/bridge/OFException+Swift.h +++ src/bridge/OFException+Swift.h @@ -27,11 +27,11 @@ OF_ASSUME_NONNULL_BEGIN @interface OFException (Swift) #ifdef OF_HAVE_BLOCKS -/*! +/** * @brief Execute the specified try block and call the catch block if an * OFException occurred. * * @note This is only useful to catch OFExceptions in Swift. * @@ -39,11 +39,11 @@ * @param catch The catch block to execute if an OFException occurred */ + (void)try: (void (^)(void))try catch: (void (^)(OF_KINDOF(OFException *)))catch; -/*! +/** * @brief Execute the specified try block and finally call the finally block. * * @note This is only useful for Swift. * * @param try The try block to execute @@ -50,11 +50,11 @@ * @param finally The finally block to call at the end */ + (void)try: (void (^)(void))try finally: (void (^)(void))finally; -/*! +/** * @brief Execute the specified try block and call the catch block if an * OFException occurred and finally call the finally block. * * @note This is only useful to catch OFExceptions in Swift. * @@ -65,14 +65,14 @@ + (void)try: (void (^)(void))try catch: (void (^)(OF_KINDOF(OFException *)))catch finally: (void (^)(void))finally; #endif -/*! +/** * @brief Raises the exception. * * @note This is only useful to raise OFExceptions in Swift. */ - (void)throw OF_NO_RETURN; @end OF_ASSUME_NONNULL_END Index: src/bridge/OFNumber+NSObject.h ================================================================== --- src/bridge/OFNumber+NSObject.h +++ src/bridge/OFNumber+NSObject.h @@ -35,11 +35,11 @@ extern int _OFNumber_NSObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category OFNumber (NSObject) \ * OFNumber+NSObject.h ObjFWBridge/OFNumber+NSObject.h * * @brief Support for bridging OFNumbers to NSNumbers. */ Index: src/bridge/OFNumber+NSObject.m ================================================================== --- src/bridge/OFNumber+NSObject.m +++ src/bridge/OFNumber+NSObject.m @@ -22,11 +22,11 @@ #import "OFInvalidArgumentException.h" int _OFNumber_NSObject_reference; @implementation OFNumber (NSObject) -- (id)NSObject +- (NSNumber *)NSObject { const char *type = self.objCType; if (strcmp(type, "B") == 0) return [NSNumber numberWithBool: self.boolValue]; Index: src/bridge/OFSet+NSObject.h ================================================================== --- src/bridge/OFSet+NSObject.h +++ src/bridge/OFSet+NSObject.h @@ -35,15 +35,15 @@ extern int _OFSet_NSObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category OFSet (NSObject) \ * OFSet+NSObject.h ObjFWBridge/OFSet+NSObject.h * @brief Support for bridging OFSets to NSSets. */ @interface OFSet (NSObject) @property (readonly, nonatomic) NSSet *NSObject; @end OF_ASSUME_NONNULL_END Index: src/bridge/OFSet+NSObject.m ================================================================== --- src/bridge/OFSet+NSObject.m +++ src/bridge/OFSet+NSObject.m @@ -20,10 +20,10 @@ #import "OFSet+NSObject.h" int _OFSet_NSObject_reference; @implementation OFSet (NSObject) -- (id)NSObject +- (NSSet *)NSObject { return [[[NSOFSet alloc] initWithOFSet: self] autorelease]; } @end Index: src/bridge/OFString+NSObject.h ================================================================== --- src/bridge/OFString+NSObject.h +++ src/bridge/OFString+NSObject.h @@ -35,11 +35,11 @@ extern int _OFString_NSObject_reference; #ifdef __cplusplus } #endif -/*! +/** * @category OFString (NSObject) \ * OFString+NSObject.h ObjFWBridge/OFString+NSObject.h * * @brief Support for bridging OFStrings to NSStrings. * Index: src/bridge/OFString+NSObject.m ================================================================== --- src/bridge/OFString+NSObject.m +++ src/bridge/OFString+NSObject.m @@ -22,11 +22,11 @@ #import "OFInitializationFailedException.h" int _OFString_NSObject_reference; @implementation OFString (NSObject) -- (id)NSObject +- (NSString *)NSObject { NSString *string = [NSString stringWithUTF8String: self.UTF8String]; if (string == nil) @throw [OFInitializationFailedException Index: src/exceptions/OFAcceptFailedException.h ================================================================== --- src/exceptions/OFAcceptFailedException.h +++ src/exceptions/OFAcceptFailedException.h @@ -21,11 +21,11 @@ # error No sockets available! #endif OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFAcceptFailedException \ * OFAcceptFailedException.h ObjFW/OFAcceptFailedException.h * * @brief An exception indicating that accepting a connection failed. */ @@ -33,23 +33,23 @@ { id _socket; int _errNo; } -/*! +/** * @brief The socket which could not accept a connection. */ @property (readonly, nonatomic) id socket; -/*! +/** * @brief The errno from when the exception was created. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased accept failed exception. * * @param socket The socket which could not accept a connection * @param errNo The errno for the error * @return A new, autoreleased accept failed exception @@ -57,11 +57,11 @@ + (instancetype)exceptionWithSocket: (id)socket errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated accept failed exception. * * @param socket The socket which could not accept a connection * @param errNo The errno for the error * @return An initialized accept failed exception Index: src/exceptions/OFAllocFailedException.h ================================================================== --- src/exceptions/OFAllocFailedException.h +++ src/exceptions/OFAllocFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFString; -/*! +/** * @class OFAllocFailedException \ * OFAllocFailedException.h ObjFW/OFAllocFailedException.h * * @brief An exception indicating an object could not be allocated. * @@ -38,14 +38,14 @@ */ @interface OFAllocFailedException: OFObject + (instancetype)exception OF_UNAVAILABLE; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Returns a description of the exception. * * @return A description of the exception */ - (OFString *)description; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFAlreadyConnectedException.h ================================================================== --- src/exceptions/OFAlreadyConnectedException.h +++ src/exceptions/OFAlreadyConnectedException.h @@ -21,11 +21,11 @@ # error No sockets available! #endif OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFAlreadyConnectedException \ * OFAlreadyConnectedException.h ObjFW/OFAlreadyConnectedException.h * * @brief An exception indicating an attempt to connect or bind an already * connected or bound socket. @@ -33,28 +33,28 @@ @interface OFAlreadyConnectedException: OFException { id _socket; } -/*! +/** * @brief The socket which is already connected. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id socket; -/*! +/** * @brief Creates a new, autoreleased already connected exception. * * @param socket The socket which is already connected * @return A new, autoreleased already connected exception */ + (instancetype)exceptionWithSocket: (nullable id)socket; -/*! +/** * @brief Initializes an already allocated already connected exception. * * @param socket The socket which is already connected * @return An initialized already connected exception */ - (instancetype)initWithSocket: (nullable id)socket OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFBindFailedException.h ================================================================== --- src/exceptions/OFBindFailedException.h +++ src/exceptions/OFBindFailedException.h @@ -23,11 +23,11 @@ #import "socket.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFBindFailedException \ * OFBindFailedException.h ObjFW/OFBindFailedException.h * * @brief An exception indicating that binding a socket failed. */ @@ -40,38 +40,38 @@ /* IPX */ uint8_t _packetType; int _errNo; } -/*! +/** * @brief The host on which binding failed. */ @property (readonly, nonatomic) OFString *host; -/*! +/** * @brief The port on which binding failed. */ @property (readonly, nonatomic) uint16_t port; -/*! +/** * @brief The IPX packet type for which binding failed. */ @property (readonly, nonatomic) uint8_t packetType; -/*! +/** * @brief The socket which could not be bound. */ @property (readonly, nonatomic) id socket; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased bind failed exception. * * @param host The host on which binding failed * @param port The port on which binding failed * @param socket The socket which could not be bound @@ -81,11 +81,11 @@ + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; -/*! +/** * @brief Creates a new, autoreleased bind failed exception. * * @param port The IPX port to which binding failed * @param packetType The IPX packet type for which binding failed * @param socket The socket which could not be bound @@ -97,11 +97,11 @@ socket: (id)socket errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated bind failed exception. * * @param host The host on which binding failed * @param port The port on which binding failed * @param socket The socket which could not be bound @@ -111,11 +111,11 @@ - (instancetype)initWithHost: (OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated bind failed exception. * * @param port The IPX port to which binding failed * @param packetType The IPX packet type for which binding failed * @param socket The socket which could not be bound Index: src/exceptions/OFChangeCurrentDirectoryPathFailedException.h ================================================================== --- src/exceptions/OFChangeCurrentDirectoryPathFailedException.h +++ src/exceptions/OFChangeCurrentDirectoryPathFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFChangeCurrentDirectoryPathFailedException \ * OFChangeCurrentDirectoryPathFailedException.h \ * ObjFW/OFChangeCurrentDirectoryPathFailedException.h * * @brief An exception indicating that changing the current directory path @@ -31,24 +31,24 @@ { OFString *_path; int _errNo; } -/*! +/** * @brief The path of the directory to which the current path could not be * changed. */ @property (readonly, nonatomic) OFString *path; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased change current directory path failed * exception. * * @param path The path of the directory to which the current path could not be * changed @@ -58,11 +58,11 @@ + (instancetype)exceptionWithPath: (OFString *)path errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated change directory failed exception. * * @param path The path of the directory to which the current path could not be * changed * @param errNo The errno of the error that occurred Index: src/exceptions/OFChecksumMismatchException.h ================================================================== --- src/exceptions/OFChecksumMismatchException.h +++ src/exceptions/OFChecksumMismatchException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFChecksumMismatchException \ * OFChecksumMismatchException.h ObjFW/OFChecksumMismatchException.h * * @brief An exception indicating that a checksum did not match. */ @@ -28,23 +28,23 @@ @interface OFChecksumMismatchException: OFException { OFString *_actualChecksum, *_expectedChecksum; } -/*! +/** * @brief The actual checksum calculated. */ @property (readonly, nonatomic) OFString *actualChecksum; -/*! +/** * @brief The expected checksum. */ @property (readonly, nonatomic) OFString *expectedChecksum; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased checksum mismatch exception. * * @param actualChecksum The actual checksum calculated * @param expectedChecksum The expected checksum * @return A new, autoreleased checksum mismatch exception. @@ -52,11 +52,11 @@ + (instancetype)exceptionWithActualChecksum: (OFString *)actualChecksum expectedChecksum: (OFString *)expectedChecksum; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated checksum mismatch exception. * * @param actualChecksum The actual checksum calculated * @param expectedChecksum The expected checksum * @return An initialized checksum mismatch exception. Index: src/exceptions/OFConditionBroadcastFailedException.h ================================================================== --- src/exceptions/OFConditionBroadcastFailedException.h +++ src/exceptions/OFConditionBroadcastFailedException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFCondition; -/*! +/** * @class OFConditionBroadcastFailedException \ * OFConditionBroadcastFailedException.h \ * ObjFW/OFConditionBroadcastFailedException.h * * @brief An exception indicating broadcasting a condition failed. @@ -36,31 +36,31 @@ { OFCondition *_condition; int _errNo; } -/*! +/** * @brief The condition which could not be broadcasted. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFCondition *condition; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Returns a new, autoreleased condition broadcast failed exception. * * @param condition The condition which could not be broadcasted * @param errNo The errno of the error that occurred * @return A new, autoreleased condition broadcast failed exception */ + (instancetype)exceptionWithCondition: (nullable OFCondition *)condition errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated condition broadcast failed exception. * * @param condition The condition which could not be broadcasted * @param errNo The errno of the error that occurred * @return An initialized condition broadcast failed exception Index: src/exceptions/OFConditionSignalFailedException.h ================================================================== --- src/exceptions/OFConditionSignalFailedException.h +++ src/exceptions/OFConditionSignalFailedException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFCondition; -/*! +/** * @class OFConditionSignalFailedException \ * OFConditionSignalFailedException.h \ * ObjFW/OFConditionSignalFailedException.h * * @brief An exception indicating signaling a condition failed. @@ -36,31 +36,31 @@ { OFCondition *_condition; int _errNo; } -/*! +/** * @brief The condition which could not be signaled. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFCondition *condition; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Creates a new, autoreleased condition signal failed exception. * * @param condition The condition which could not be signaled * @param errNo The errno of the error that occurred * @return A new, autoreleased condition signal failed exception */ + (instancetype)exceptionWithCondition: (nullable OFCondition *)condition errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated condition signal failed exception. * * @param condition The condition which could not be signaled * @param errNo The errno of the error that occurred * @return An initialized condition signal failed exception Index: src/exceptions/OFConditionStillWaitingException.h ================================================================== --- src/exceptions/OFConditionStillWaitingException.h +++ src/exceptions/OFConditionStillWaitingException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFCondition; -/*! +/** * @class OFConditionStillWaitingException \ * OFConditionStillWaitingException.h \ * ObjFW/OFConditionStillWaitingException.h * * @brief An exception indicating that a thread is still waiting for a @@ -36,24 +36,24 @@ @interface OFConditionStillWaitingException: OFException { OFCondition *_condition; } -/*! +/** * @brief The condition for which is still being waited. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFCondition *condition; -/*! +/** * @brief Creates a new, autoreleased condition still waiting exception. * * @param condition The condition for which is still being waited * @return A new, autoreleased condition still waiting exception */ + (instancetype)exceptionWithCondition: (nullable OFCondition *)condition; -/*! +/** * @brief Initializes an already allocated condition still waiting exception. * * @param condition The condition for which is still being waited * @return An initialized condition still waiting exception */ Index: src/exceptions/OFConditionWaitFailedException.h ================================================================== --- src/exceptions/OFConditionWaitFailedException.h +++ src/exceptions/OFConditionWaitFailedException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFCondition; -/*! +/** * @class OFConditionWaitFailedException \ * OFConditionWaitFailedException.h \ * ObjFW/OFConditionWaitFailedException.h * * @brief An exception indicating waiting for a condition failed. @@ -36,31 +36,31 @@ { OFCondition *_condition; int _errNo; } -/*! +/** * @brief The condition for which could not be waited. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFCondition *condition; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Creates a new, autoreleased condition wait failed exception. * * @param condition The condition for which could not be waited * @param errNo The errno of the error that occurred * @return A new, autoreleased condition wait failed exception */ + (instancetype)exceptionWithCondition: (nullable OFCondition *)condition errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated condition wait failed exception. * * @param condition The condition for which could not be waited * @param errNo The errno of the error that occurred * @return An initialized condition wait failed exception Index: src/exceptions/OFConnectionFailedException.h ================================================================== --- src/exceptions/OFConnectionFailedException.h +++ src/exceptions/OFConnectionFailedException.h @@ -23,11 +23,11 @@ #import "socket.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFConnectionFailedException \ * OFConnectionFailedException.h ObjFW/OFConnectionFailedException.h * * @brief An exception indicating that a connection could not be established. */ @@ -39,43 +39,43 @@ unsigned char _node[IPX_NODE_LEN]; uint32_t _network; int _errNo; } -/*! +/** * @brief The socket which could not connect. */ @property (readonly, nonatomic) id socket; -/*! +/** * @brief The host to which the connection failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *host; -/*! +/** * @brief The port on the host to which the connection failed. */ @property (readonly, nonatomic) uint16_t port; -/*! +/** * @brief The IPX node to which the connection failed. */ @property (readonly, nonatomic) unsigned char *node; -/*! +/** * @brief The IPX network of the node to which the connection failed. */ @property (readonly, nonatomic) uint32_t network; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased connection failed exception. * * @param host The host to which the connection failed * @param port The port on the host to which the connection failed * @param socket The socket which could not connect @@ -85,11 +85,11 @@ + (instancetype)exceptionWithHost: (nullable OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; -/*! +/** * @brief Creates a new, autoreleased connection failed exception. * * @param node The node to which the connection failed * @param network The IPX network of the node to which the connection failed * @param port The port on the node to which the connection failed @@ -103,11 +103,11 @@ socket: (id)socket errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated connection failed exception. * * @param host The host to which the connection failed * @param port The port on the host to which the connection failed * @param socket The socket which could not connect @@ -117,11 +117,11 @@ - (instancetype)initWithHost: (nullable OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated connection failed exception. * * @param node The node to which the connection failed * @param network The IPX network of the node to which the connection failed * @param port The port on the node to which the connection failed Index: src/exceptions/OFCopyItemFailedException.h ================================================================== --- src/exceptions/OFCopyItemFailedException.h +++ src/exceptions/OFCopyItemFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFCopyItemFailedException \ * OFCopyItemFailedException.h ObjFW/OFCopyItemFailedException.h * * @brief An exception indicating that copying a item failed. */ @@ -31,28 +31,28 @@ { OFURL *_sourceURL, *_destinationURL; int _errNo; } -/*! +/** * @brief The path of the source item. */ @property (readonly, nonatomic) OFURL *sourceURL; -/*! +/** * @brief The destination path. */ @property (readonly, nonatomic) OFURL *destinationURL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased copy item failed exception. * * @param sourceURL The original path * @param destinationURL The new path * @param errNo The errno of the error that occurred @@ -62,11 +62,11 @@ destinationURL: (OFURL *)destinationURL errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated copy item failed exception. * * @param sourceURL The original path * @param destinationURL The new path * @param errNo The errno of the error that occurred Index: src/exceptions/OFCreateDirectoryFailedException.h ================================================================== --- src/exceptions/OFCreateDirectoryFailedException.h +++ src/exceptions/OFCreateDirectoryFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFCreateDirectoryFailedException \ * OFCreateDirectoryFailedException.h \ * ObjFW/OFCreateDirectoryFailedException.h * * @brief An exception indicating a directory couldn't be created. @@ -32,23 +32,23 @@ { OFURL *_URL; int _errNo; } -/*! +/** * @brief The URL of the directory which couldn't be created. */ @property (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased create directory failed exception. * * @param URL The URL of the directory which could not be created * @param errNo The errno of the error that occurred * @return A new, autoreleased create directory failed exception @@ -56,11 +56,11 @@ + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated create directory failed exception. * * @param URL The URL of the directory which could not be created * @param errNo The errno of the error that occurred * @return An initialized create directory failed exception Index: src/exceptions/OFCreateSymbolicLinkFailedException.h ================================================================== --- src/exceptions/OFCreateSymbolicLinkFailedException.h +++ src/exceptions/OFCreateSymbolicLinkFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFCreateSymbolicLinkFailedException \ * OFCreateSymbolicLinkFailedException.h \ * ObjFW/OFCreateSymbolicLinkFailedException.h * * @brief An exception indicating that creating a symbolic link failed. @@ -33,28 +33,28 @@ OFURL *_URL; OFString *_target; int _errNo; } -/*! +/** * @brief The URL at which the symlink should have been created. */ @property (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief The target for the symlink. */ @property (readonly, nonatomic) OFString *target; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased create symbolic link failed exception. * * @param URL The URL where the symlink should have been created * @param target The target for the symbolic link * @param errNo The errno of the error that occurred @@ -64,11 +64,11 @@ target: (OFString *)target errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated create symbolic link failed * exception. * * @param URL The URL where the symlink should have been created * @param target The target for the symbolic link Index: src/exceptions/OFCreateWindowsRegistryKeyFailedException.h ================================================================== --- src/exceptions/OFCreateWindowsRegistryKeyFailedException.h +++ src/exceptions/OFCreateWindowsRegistryKeyFailedException.h @@ -20,11 +20,11 @@ #include OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFCreateWindowsRegistryKeyFailedException \ * OFCreateWindowsRegistryKeyFailedException.h \ * ObjFW/OFCreateWindowsRegistryKeyFailedException.h * * @brief An exception indicating that creating a Windows registry key failed. @@ -37,43 +37,43 @@ REGSAM _securityAndAccessRights; LPSECURITY_ATTRIBUTES _Nullable _securityAttributes; LSTATUS _status; } -/*! +/** * @brief The registry key on which creating the subkey failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; -/*! +/** * @brief The path for the subkey that could not be created. */ @property (readonly, nonatomic) OFString *path; -/*! +/** * @brief The options for the subkey that could not be created. */ @property (readonly, nonatomic) DWORD options; -/*! +/** * @brief The security and access rights for the subkey that could not be * created. */ @property (readonly, nonatomic) REGSAM securityAndAccessRights; -/*! +/** * @brief The security options for the subkey that could not be created. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) LPSECURITY_ATTRIBUTES securityAttributes; -/*! +/** * @brief The status returned by RegCreateKeyEx(). */ @property (readonly, nonatomic) LSTATUS status; -/*! +/** * @brief Creates a new, autoreleased create Windows registry key failed * exception. * * @param registryKey The registry key on which creating the subkey failed * @param path The path for the subkey that could not be created @@ -93,11 +93,11 @@ securityAttributes: (nullable LPSECURITY_ATTRIBUTES)securityAttributes status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated create Windows registry key failed * exception. * * @param registryKey The registry key on which creating the subkey failed * @param path The path for the subkey that could not be created Index: src/exceptions/OFDNSQueryFailedException.h ================================================================== --- src/exceptions/OFDNSQueryFailedException.h +++ src/exceptions/OFDNSQueryFailedException.h @@ -20,11 +20,11 @@ #import "OFDNSResolver.h" #import "OFDNSResourceRecord.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFDNSQueryFailedException \ * OFDNSQueryFailedException.h ObjFW/OFDNSQueryFailedException.h * * @brief An exception indicating that a DNS query failed. */ @@ -32,31 +32,31 @@ { OFDNSQuery *_query; of_dns_resolver_error_t _error; } -/*! +/** * @brief The query which could not be performed. */ @property (readonly, nonatomic) OFDNSQuery *query; -/*! +/** * @brief The error from the resolver. */ @property (readonly, nonatomic) of_dns_resolver_error_t error; -/*! +/** * @brief Creates a new, autoreleased DNS query failed exception. * * @param query The query which could not be performed * @param error The error from the resolver * @return A new, autoreleased address translation failed exception */ + (instancetype)exceptionWithQuery: (OFDNSQuery *)query error: (of_dns_resolver_error_t)error; -/*! +/** * @brief Initializes an already allocated DNS query failed exception. * * @param query The query which could not be performed * @param error The error from the resolver * @return An initialized address translation failed exception Index: src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h ================================================================== --- src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h +++ src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h @@ -20,11 +20,11 @@ #include OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFDeleteWindowsRegistryKeyFailedException \ * OFDeleteWindowsRegistryKeyFailedException.h \ * ObjFW/OFDeleteWindowsRegistryKeyFailedException.h * * @brief An exception indicating that deleting a Windows registry key failed. @@ -34,26 +34,26 @@ OFWindowsRegistryKey *_registryKey; OFString *_subkeyPath; LSTATUS _status; } -/*! +/** * @brief The registry key on which deleting the subkey failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; -/*! +/** * @brief The path of the subkey which could not be deleted. */ @property (readonly, nonatomic) OFString *subkeyPath; -/*! +/** * @brief The status returned by RegDeleteKeyEx(). */ @property (readonly, nonatomic) LSTATUS status; -/*! +/** * @brief Creates a new, autoreleased delete Windows registry key failed * exception. * * @param registryKey The registry key on which deleting the subkey failed * @param subkeyPath The path of the subkey which could not be deleted @@ -64,11 +64,11 @@ subkeyPath: (OFString *)subkeyPath status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated delete Windows registry key failed * exception. * * @param registryKey The registry key on which deleting the subkey failed * @param subkeyPath The path of the subkey which could not be deleted Index: src/exceptions/OFDeleteWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFDeleteWindowsRegistryValueFailedException.h +++ src/exceptions/OFDeleteWindowsRegistryValueFailedException.h @@ -20,11 +20,11 @@ #include OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFDeleteWindowsRegistryValueFailedException \ * OFDeleteWindowsRegistryValueFailedException.h \ * ObjFW/OFDeleteWindowsRegistryValueFailedException.h * * @brief An exception indicating that deleting a Windows registry value failed. @@ -34,26 +34,26 @@ OFWindowsRegistryKey *_registryKey; OFString *_Nullable _value; LSTATUS _status; } -/*! +/** * @brief The registry key on which deleting the value failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; -/*! +/** * @brief The value which could not be deleted. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; -/*! +/** * @brief The status returned by RegDeleteValueEx(). */ @property (readonly, nonatomic) LSTATUS status; -/*! +/** * @brief Creates a new, autoreleased delete Windows registry value failed * exception. * * @param registryKey The registry key on which deleting the value failed * @param value The value which could not be deleted @@ -64,11 +64,11 @@ value: (nullable OFString *)value status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated delete Windows registry value failed * exception. * * @param registryKey The registry key on which deleting the value failed * @param value The value which could not be deleted Index: src/exceptions/OFEnumerationMutationException.h ================================================================== --- src/exceptions/OFEnumerationMutationException.h +++ src/exceptions/OFEnumerationMutationException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFEnumerationMutationException \ * OFEnumerationMutationException.h \ * ObjFW/OFEnumerationMutationException.h * * @brief An exception indicating that a mutation was detected during @@ -30,32 +30,32 @@ @interface OFEnumerationMutationException: OFException { id _object; } -/*! +/** * @brief The object which was mutated during enumeration. */ @property (readonly, nonatomic) id object; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased enumeration mutation exception. * * @param object The object which was mutated during enumeration * @return A new, autoreleased enumeration mutation exception */ + (instancetype)exceptionWithObject: (id)object; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated enumeration mutation exception. * * @param object The object which was mutated during enumeration * @return An initialized enumeration mutation exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFException.h ================================================================== --- src/exceptions/OFException.h +++ src/exceptions/OFException.h @@ -135,11 +135,11 @@ # ifndef EWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK # endif #endif -/*! +/** * @class OFException OFException.h ObjFW/OFException.h * * @brief The base class for all exceptions in ObjFW * * The OFException class is the base class for all exceptions in ObjFW, except @@ -148,25 +148,25 @@ @interface OFException: OFObject { void *_backtrace[OF_BACKTRACE_SIZE]; } -/*! +/** * @brief Creates a new, autoreleased exception. * * @return A new, autoreleased exception */ + (instancetype)exception; -/*! +/** * @brief Returns a description of the exception. * * @return A description of the exception */ - (OFString *)description; -/*! +/** * @brief Returns a backtrace of when the exception was created or nil if no * backtrace is available. * * @return A backtrace of when the exception was created */ Index: src/exceptions/OFGetCurrentDirectoryPathFailedException.h ================================================================== --- src/exceptions/OFGetCurrentDirectoryPathFailedException.h +++ src/exceptions/OFGetCurrentDirectoryPathFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFGetCurrentDirectoryPathFailedException \ * OFGetCurrentDirectoryPathFailedException.h \ * ObjFW/OFGetCurrentDirectoryPathFailedException.h * * @brief An exception indicating that getting the current directory path @@ -30,18 +30,18 @@ @interface OFGetCurrentDirectoryPathFailedException: OFException { int _errNo; } -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased get current directory path failed * exception. * * @param errNo The errno of the error that occurred * @return A new, autoreleased get current directory failed exception @@ -48,11 +48,11 @@ */ + (instancetype)exceptionWithErrNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated get current directory path failed * exception. * * @param errNo The errno of the error that occurred * @return An initialized get current directory path failed exception Index: src/exceptions/OFGetOptionFailedException.h ================================================================== --- src/exceptions/OFGetOptionFailedException.h +++ src/exceptions/OFGetOptionFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFGetOptionFailedException \ * OFGetOptionFailedException.h ObjFW/OFGetOptionFailedException.h * * @brief An exception indicating that getting an option for an object failed. */ @@ -29,23 +29,23 @@ { id _object; int _errNo; } -/*! +/** * @brief The object for which the option could not be retrieved. */ @property (readonly, nonatomic) id object; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased get option failed exception. * * @param object The object for which the option could not be retrieved * @param errNo The errno of the error that occurred * @return A new, autoreleased get option failed exception @@ -53,11 +53,11 @@ + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated get option failed exception. * * @param object The object for which the option could not be retrieved * @param errNo The errno of the error that occurred * @return An initialized get option failed exception Index: src/exceptions/OFGetWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFGetWindowsRegistryValueFailedException.h +++ src/exceptions/OFGetWindowsRegistryValueFailedException.h @@ -20,11 +20,11 @@ #include OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFGetWindowsRegistryValueFailedException \ * OFGetWindowsRegistryValueFailedException.h \ * ObjFW/OFGetWindowsRegistryValueFailedException.h * * @brief An exception indicating that getting a Windows registry value failed. @@ -35,26 +35,26 @@ OFString *_Nullable _value; DWORD _flags; LSTATUS _status; } -/*! +/** * @brief The registry key on which getting the value at the key path failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; -/*! +/** * @brief The value which could not be retrieved. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; -/*! +/** * @brief The status returned by RegGetValueEx(). */ @property (readonly, nonatomic) LSTATUS status; -/*! +/** * @brief Creates a new, autoreleased get Windows registry value failed * exception. * * @param registryKey The registry key on which getting the value at the sub * key path failed @@ -66,11 +66,11 @@ value: (nullable OFString *)value status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated get Windows registry value failed * exception. * * @param registryKey The registry key on which getting the value at the sub * key path failed Index: src/exceptions/OFHTTPRequestFailedException.h ================================================================== --- src/exceptions/OFHTTPRequestFailedException.h +++ src/exceptions/OFHTTPRequestFailedException.h @@ -24,11 +24,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFHTTPRequest; @class OFHTTPResponse; -/*! +/** * @class OFHTTPRequestFailedException \ * OFHTTPRequestFailedException.h \ * ObjFW/OFHTTPRequestFailedException.h * * @brief An exception indicating that an HTTP request failed. @@ -37,23 +37,23 @@ { OFHTTPRequest *_request; OFHTTPResponse *_response; } -/*! +/** * @brief The HTTP request which failed. */ @property (readonly, nonatomic) OFHTTPRequest *request; -/*! +/** * @brief The response for the failed HTTP request. */ @property (readonly, nonatomic) OFHTTPResponse *response; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased HTTP request failed exception. * * @param request The HTTP request which failed * @param response The response for the failed HTTP request * @return A new, autoreleased HTTP request failed exception @@ -61,11 +61,11 @@ + (instancetype)exceptionWithRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated HTTP request failed exception. * * @param request The HTTP request which failed * @param response The response for the failed HTTP request * @return A new HTTP request failed exception Index: src/exceptions/OFHashAlreadyCalculatedException.h ================================================================== --- src/exceptions/OFHashAlreadyCalculatedException.h +++ src/exceptions/OFHashAlreadyCalculatedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFHashAlreadyCalculatedException \ * OFHashAlreadyCalculatedException.h \ * ObjFW/OFHashAlreadyCalculatedException.h * * @brief An exception indicating that the hash has already been calculated. @@ -29,32 +29,32 @@ @interface OFHashAlreadyCalculatedException: OFException { id _object; } -/*! +/** * @brief The hash which has already been calculated. */ @property (readonly, nonatomic) id object; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased hash already calculated exception. * * @param object The hash which has already been calculated * @return A new, autoreleased hash already calculated exception */ + (instancetype)exceptionWithObject: (id)object; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated hash already calculated exception. * * @param object The hash which has already been calculated * @return An initialized hash already calculated exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFInitializationFailedException.h ================================================================== --- src/exceptions/OFInitializationFailedException.h +++ src/exceptions/OFInitializationFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFInitializationFailedException \ * OFInitializationFailedException.h \ * ObjFW/OFInitializationFailedException.h * * @brief An exception indicating that initializing something failed. @@ -29,28 +29,28 @@ @interface OFInitializationFailedException: OFException { Class _inClass; } -/*! +/** * @brief The class for which initialization failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class inClass; -/*! +/** * @brief Creates a new, autoreleased initialization failed exception. * * @param class_ The class for which initialization failed * @return A new, autoreleased initialization failed exception */ + (instancetype)exceptionWithClass: (nullable Class)class_; -/*! +/** * @brief Initializes an already allocated initialization failed exception. * * @param class_ The class for which initialization failed * @return An initialized initialization failed exception */ - (instancetype)initWithClass: (nullable Class)class_ OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFInvalidArgumentException.h ================================================================== --- src/exceptions/OFInvalidArgumentException.h +++ src/exceptions/OFInvalidArgumentException.h @@ -17,15 +17,15 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFInvalidArgumentException \ * OFInvalidArgumentException.h ObjFW/OFInvalidArgumentException.h * * @brief An exception indicating that the argument is invalid for this method. */ @interface OFInvalidArgumentException: OFException @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFInvalidEncodingException.h ================================================================== --- src/exceptions/OFInvalidEncodingException.h +++ src/exceptions/OFInvalidEncodingException.h @@ -17,15 +17,15 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFInvalidEncodingException \ * OFInvalidEncodingException.h ObjFW/OFInvalidEncodingException.h * * @brief An exception indicating that the encoding is invalid for this object. */ @interface OFInvalidEncodingException: OFException @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFInvalidFormatException.h ================================================================== --- src/exceptions/OFInvalidFormatException.h +++ src/exceptions/OFInvalidFormatException.h @@ -17,15 +17,15 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFInvalidFormatException \ * OFInvalidFormatException.h ObjFW/OFInvalidFormatException.h * * @brief An exception indicating that the format is invalid. */ @interface OFInvalidFormatException: OFException @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFInvalidJSONException.h ================================================================== --- src/exceptions/OFInvalidJSONException.h +++ src/exceptions/OFInvalidJSONException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFInvalidJSONException \ * OFInvalidJSONException.h ObjFW/OFInvalidJSONException.h * * @brief An exception indicating a JSON representation is invalid. */ @@ -29,23 +29,23 @@ { OFString *_string; size_t _line; } -/*! +/** * @brief The string containing the invalid JSON representation. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *string; -/*! +/** * @brief The line in which parsing the JSON representation failed. */ @property (readonly, nonatomic) size_t line; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased invalid JSON exception. * * @param string The string containing the invalid JSON representation * @param line The line in which the parsing error was encountered * @return A new, autoreleased invalid JSON exception @@ -53,11 +53,11 @@ + (instancetype)exceptionWithString: (nullable OFString *)string line: (size_t)line; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated invalid JSON exception. * * @param string The string containing the invalid JSON representation * @param line The line in which the parsing error was encountered * @return An initialized invalid JSON exception Index: src/exceptions/OFInvalidServerReplyException.h ================================================================== --- src/exceptions/OFInvalidServerReplyException.h +++ src/exceptions/OFInvalidServerReplyException.h @@ -17,15 +17,15 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFInvalidServerReplyException \ * OFInvalidServerReplyException.h ObjFW/OFInvalidServerReplyException.h * * @brief An exception indicating that the server sent an invalid reply. */ @interface OFInvalidServerReplyException: OFException @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFLinkFailedException.h ================================================================== --- src/exceptions/OFLinkFailedException.h +++ src/exceptions/OFLinkFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFLinkFailedException \ * OFLinkFailedException.h ObjFW/OFLinkFailedException.h * * @brief An exception indicating that creating a link failed. */ @@ -31,28 +31,28 @@ { OFURL *_sourceURL, *_destinationURL; int _errNo; } -/*! +/** * @brief A URL with the source for the link. */ @property (readonly, nonatomic) OFURL *sourceURL; -/*! +/** * @brief A URL with the destination for the link. */ @property (readonly, nonatomic) OFURL *destinationURL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased link failed exception. * * @param sourceURL The source for the link * @param destinationURL The destination for the link * @param errNo The errno of the error that occurred @@ -62,11 +62,11 @@ destinationURL: (OFURL *)destinationURL errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated link failed exception. * * @param sourceURL The source for the link * @param destinationURL The destination for the link * @param errNo The errno of the error that occurred Index: src/exceptions/OFListenFailedException.h ================================================================== --- src/exceptions/OFListenFailedException.h +++ src/exceptions/OFListenFailedException.h @@ -21,11 +21,11 @@ # error No sockets available! #endif OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFListenFailedException \ * OFListenFailedException.h ObjFW/OFListenFailedException.h * * @brief An exception indicating that listening on the socket failed. */ @@ -33,28 +33,28 @@ { id _socket; int _backlog, _errNo; } -/*! +/** * @brief The socket which failed to listen. */ @property (readonly, nonatomic) id socket; -/*! +/** * @brief The requested back log. */ @property (readonly, nonatomic) int backlog; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased listen failed exception. * * @param socket The socket which failed to listen * @param backlog The requested size of the back log * @param errNo The errno of the error that occurred @@ -64,11 +64,11 @@ backlog: (int)backlog errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated listen failed exception * * @param socket The socket which failed to listen * @param backlog The requested size of the back log * @param errNo The errno of the error that occurred Index: src/exceptions/OFLoadPluginFailedException.h ================================================================== --- src/exceptions/OFLoadPluginFailedException.h +++ src/exceptions/OFLoadPluginFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFLoadPluginFailedException \ * OFLoadPluginFailedException.h ObjFW/OFLoadPluginFailedException.h * * @brief An exception indicating a plugin could not be loaded. */ @@ -28,23 +28,23 @@ @interface OFLoadPluginFailedException: OFException { OFString *_path, *_Nullable _error; } -/*! +/** * @brief The path of the plugin which could not be loaded */ @property (readonly, nonatomic) OFString *path; -/*! +/** * @brief The error why the plugin could not be loaded, as a string */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *error; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased load plugin failed exception. * * @param path The path of the plugin which could not be loaded * @param error The error why the plugin could not be loaded, as a string * @return A new, autoreleased load plugin failed exception @@ -52,11 +52,11 @@ + (instancetype)exceptionWithPath: (OFString *)path error: (nullable OFString *)error; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated load plugin failed exception. * * @param path The path of the plugin which could not be loaded * @param error The error why the plugin could not be loaded, as a string * @return An initialized load plugin failed exception Index: src/exceptions/OFLockFailedException.h ================================================================== --- src/exceptions/OFLockFailedException.h +++ src/exceptions/OFLockFailedException.h @@ -18,11 +18,11 @@ #import "OFException.h" #import "OFLocking.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFLockFailedException \ * OFLockFailedException.h ObjFW/OFLockFailedException.h * * @brief An exception indicating that locking a lock failed. */ @@ -30,31 +30,31 @@ { id _lock; int _errNo; } -/*! +/** * @brief The lock which could not be locked. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id lock; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Creates a new, autoreleased lock failed exception. * * @param lock The lock which could not be locked * @param errNo The errno of the error that occurred * @return A new, autoreleased lock failed exception */ + (instancetype)exceptionWithLock: (nullable id )lock errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated lock failed exception. * * @param lock The lock which could not be locked * @param errNo The errno of the error that occurred * @return An initialized lock failed exception Index: src/exceptions/OFLockFailedException.m ================================================================== --- src/exceptions/OFLockFailedException.m +++ src/exceptions/OFLockFailedException.m @@ -57,8 +57,8 @@ - (OFString *)description { return [OFString stringWithFormat: @"A lock of type %@ could not be locked: %s", - _lock.class, strerror(_errNo)]; + [_lock class], strerror(_errNo)]; } @end Index: src/exceptions/OFMalformedXMLException.h ================================================================== --- src/exceptions/OFMalformedXMLException.h +++ src/exceptions/OFMalformedXMLException.h @@ -19,11 +19,11 @@ @class OFXMLParser; OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMalformedXMLException \ * OFMalformedXMLException.h ObjFW/OFMalformedXMLException.h * * @brief An exception indicating that a parser encountered malformed XML. */ @@ -30,24 +30,24 @@ @interface OFMalformedXMLException: OFException { OFXMLParser *_parser; } -/*! +/** * @brief The parser which encountered malformed XML. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFXMLParser *parser; -/*! +/** * @brief Creates a new, autoreleased malformed XML exception. * * @param parser The parser which encountered malformed XML * @return A new, autoreleased malformed XML exception */ + (instancetype)exceptionWithParser: (nullable OFXMLParser *)parser; -/*! +/** * @brief Initializes an already allocated malformed XML exception. * * @param parser The parser which encountered malformed XML * @return An initialized malformed XML exception */ Index: src/exceptions/OFMemoryNotPartOfObjectException.h ================================================================== --- src/exceptions/OFMemoryNotPartOfObjectException.h +++ src/exceptions/OFMemoryNotPartOfObjectException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFMemoryNotPartOfObjectException \ * OFMemoryNotPartOfObjectException.h \ * ObjFW/OFMemoryNotPartOfObjectException.h * * @brief An exception indicating the given memory is not part of the object. @@ -30,23 +30,23 @@ { void *_Nullable _pointer; id _object; } -/*! +/** * @brief A pointer to the memory which is not part of the object. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *pointer; -/*! +/** * @brief The object which the memory is not part of. */ @property (readonly, nonatomic) id object; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased memory not part of object exception. * * @param pointer A pointer to the memory that is not part of the object * @param object The object which the memory is not part of * @return A new, autoreleased memory not part of object exception @@ -54,11 +54,11 @@ + (instancetype)exceptionWithPointer: (nullable void *)pointer object: (id)object; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated memory not part of object exception. * * @param pointer A pointer to the memory that is not part of the object * @param object The object which the memory is not part of * @return An initialized memory not part of object exception Index: src/exceptions/OFMoveItemFailedException.h ================================================================== --- src/exceptions/OFMoveItemFailedException.h +++ src/exceptions/OFMoveItemFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFMoveItemFailedException \ * OFMoveItemFailedException.h ObjFW/OFMoveItemFailedException.h * * @brief An exception indicating that moving an item failed. */ @@ -31,28 +31,28 @@ { OFURL *_sourceURL, *_destinationURL; int _errNo; } -/*! +/** * @brief The original URL. */ @property (readonly, nonatomic) OFURL *sourceURL; -/*! +/** * @brief The new URL. */ @property (readonly, nonatomic) OFURL *destinationURL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased move item failed exception. * * @param sourceURL The original URL * @param destinationURL The new URL * @param errNo The errno of the error that occurred @@ -62,11 +62,11 @@ destinationURL: (OFURL *)destinationURL errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated move item failed exception. * * @param sourceURL The original URL * @param destinationURL The new URL * @param errNo The errno of the error that occurred Index: src/exceptions/OFNotImplementedException.h ================================================================== --- src/exceptions/OFNotImplementedException.h +++ src/exceptions/OFNotImplementedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFNotImplementedException \ * OFNotImplementedException.h ObjFW/OFNotImplementedException.h * * @brief An exception indicating that a method or part of it is not * implemented. @@ -30,23 +30,23 @@ { SEL _selector; id _Nullable _object; } -/*! +/** * @brief The selector which is not or not fully implemented. */ @property (readonly, nonatomic) SEL selector; -/*! +/** * @brief The object which does not (fully) implement the selector. */ @property (readonly, nonatomic) id object; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased not implemented exception. * * @param selector The selector which is not or not fully implemented * @param object The object which does not (fully) implement the selector * @return A new, autoreleased not implemented exception @@ -54,11 +54,11 @@ + (instancetype)exceptionWithSelector: (SEL)selector object: (nullable id)object; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated not implemented exception. * * @param selector The selector which is not or not fully implemented * @param object The object which does not (fully) implement the selector * @return An initialized not implemented exception Index: src/exceptions/OFNotOpenException.h ================================================================== --- src/exceptions/OFNotOpenException.h +++ src/exceptions/OFNotOpenException.h @@ -17,42 +17,42 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFNotOpenException OFNotOpenException.h ObjFW/OFNotOpenException.h * * @brief An exception indicating an object is not open, connected or bound. */ @interface OFNotOpenException: OFException { id _object; } -/*! +/** * @brief The object which is not open, connected or bound. */ @property (readonly, nonatomic) id object; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased not open exception. * * @param object The object which is not open, connected or bound * @return A new, autoreleased not open exception */ + (instancetype)exceptionWithObject: (id)object; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated not open exception. * * @param object The object which is not open, connected or bound * @return An initialized not open exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFObserveFailedException.h ================================================================== --- src/exceptions/OFObserveFailedException.h +++ src/exceptions/OFObserveFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFKernelEventObserver; -/*! +/** * @class OFObserveFailedException \ * OFObserveFailedException.h ObjFW/OFObserveFailedException.h * * @brief An exception indicating that observing failed. */ @@ -31,23 +31,23 @@ { OFKernelEventObserver *_observer; int _errNo; } -/*! +/** * @brief The observer which failed to observe. */ @property (readonly, nonatomic) OFKernelEventObserver *observer; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased observe failed exception. * * @param observer The observer which failed to observe * @param errNo The errno of the error that occurred * @return A new, autoreleased observe failed exception @@ -55,11 +55,11 @@ + (instancetype)exceptionWithObserver: (OFKernelEventObserver *)observer errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated observe failed exception. * * @param observer The observer which failed to observe * @param errNo The errno of the error that occurred * @return An initialized observe failed exception Index: src/exceptions/OFOpenItemFailedException.h ================================================================== --- src/exceptions/OFOpenItemFailedException.h +++ src/exceptions/OFOpenItemFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFOpenItemFailedException \ * OFOpenItemFailedException.h ObjFW/OFOpenItemFailedException.h * * @brief An exception indicating an item could not be opened. */ @@ -33,33 +33,33 @@ OFString *_Nullable _path; OFString *_mode; int _errNo; } -/*! +/** * @brief The URL of the item which could not be opened. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief The path of the item which could not be opened. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *path; -/*! +/** * @brief The mode in which the item should have been opened. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *mode; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased open item failed exception. * * @param URL The URL of the item which could not be opened * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred @@ -67,11 +67,11 @@ */ + (instancetype)exceptionWithURL: (OFURL *)URL mode: (nullable OFString *)mode errNo: (int)errNo; -/*! +/** * @brief Creates a new, autoreleased open item failed exception. * * @param path The path of the item which could not be opened * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred @@ -81,11 +81,11 @@ mode: (nullable OFString *)mode errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated open item failed exception. * * @param URL The URL of the item which could not be opened * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred @@ -93,11 +93,11 @@ */ - (instancetype)initWithURL: (OFURL *)URL mode: (nullable OFString *)mode errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated open item failed exception. * * @param path The path of the item which could not be opened * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred Index: src/exceptions/OFOpenWindowsRegistryKeyFailedException.h ================================================================== --- src/exceptions/OFOpenWindowsRegistryKeyFailedException.h +++ src/exceptions/OFOpenWindowsRegistryKeyFailedException.h @@ -20,11 +20,11 @@ #include OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFOpenWindowsRegistryKeyFailedException \ * OFOpenWindowsRegistryKeyFailedException.h \ * ObjFW/OFOpenWindowsRegistryKeyFailedException.h * * @brief An exception indicating that opening a Windows registry key failed. @@ -37,37 +37,37 @@ REGSAM _securityAndAccessRights; LPSECURITY_ATTRIBUTES _Nullable _securityAttributes; LSTATUS _status; } -/*! +/** * @brief The registry key on which opening the subkey failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; -/*! +/** * @brief The path for the subkey that could not be opened. */ @property (readonly, nonatomic) OFString *path; -/*! +/** * @brief The options for the subkey that could not be opened. */ @property (readonly, nonatomic) DWORD options; -/*! +/** * @brief The security and access rights for the subkey that could not be * opened. */ @property (readonly, nonatomic) REGSAM securityAndAccessRights; -/*! +/** * @brief The status returned by RegOpenKeyEx(). */ @property (readonly, nonatomic) LSTATUS status; -/*! +/** * @brief Creates a new, autoreleased open Windows registry key failed * exception. * * @param registryKey The registry key on which opening the subkey failed * @param path The path for the subkey that could not be opened @@ -84,11 +84,11 @@ securityAndAccessRights: (REGSAM)securityAndAccessRights status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated open Windows registry key failed * exception. * * @param registryKey The registry key on which opening the subkey failed * @param path The path for the subkey that could not be opened Index: src/exceptions/OFOutOfMemoryException.h ================================================================== --- src/exceptions/OFOutOfMemoryException.h +++ src/exceptions/OFOutOfMemoryException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFOutOfMemoryException \ * OFOutOfMemoryException.h ObjFW/OFOutOfMemoryException.h * * @brief An exception indicating there is not enough memory available. */ @@ -28,24 +28,24 @@ @interface OFOutOfMemoryException: OFException { size_t _requestedSize; } -/*! +/** * @brief The size of the memory that could not be allocated. */ @property (readonly, nonatomic) size_t requestedSize; -/*! +/** * @brief Creates a new, autoreleased no memory exception. * * @param requestedSize The size of the memory that could not be allocated * @return A new, autoreleased no memory exception */ + (instancetype)exceptionWithRequestedSize: (size_t)requestedSize; -/*! +/** * @brief Initializes an already allocated no memory exception. * * @param requestedSize The size of the memory that could not be allocated * @return An initialized no memory exception */ Index: src/exceptions/OFOutOfRangeException.h ================================================================== --- src/exceptions/OFOutOfRangeException.h +++ src/exceptions/OFOutOfRangeException.h @@ -17,15 +17,15 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFOutOfRangeException \ * OFOutOfRangeException.h ObjFW/OFOutOfRangeException.h * * @brief An exception indicating the given value is out of range. */ @interface OFOutOfRangeException: OFException @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFReadFailedException.h ================================================================== --- src/exceptions/OFReadFailedException.h +++ src/exceptions/OFReadFailedException.h @@ -17,15 +17,15 @@ #import "OFReadOrWriteFailedException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFReadFailedException \ * OFReadFailedException.h ObjFW/OFReadFailedException.h * * @brief An exception indicating that reading from an object failed. */ @interface OFReadFailedException: OFReadOrWriteFailedException @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFReadOrWriteFailedException.h ================================================================== --- src/exceptions/OFReadOrWriteFailedException.h +++ src/exceptions/OFReadOrWriteFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFReadOrWriteFailedException \ * OFReadOrWriteFailedException.h ObjFW/OFReadOrWriteFailedException.h * * @brief An exception indicating that reading from or writing to an object * failed. @@ -31,28 +31,28 @@ id _object; size_t _requestedLength; int _errNo; } -/*! +/** * @brief The stream which caused the read or write failed exception. */ @property (readonly, nonatomic) id object; -/*! +/** * @brief The requested length of the data that could not be read / written. */ @property (readonly, nonatomic) size_t requestedLength; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased read or write failed exception. * * @param object The object from which reading or to which writing failed * @param requestedLength The requested length of the data that could not be * read / written @@ -63,11 +63,11 @@ requestedLength: (size_t)requestedLength errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated read or write failed exception. * * @param object The object from which reading or to which writing failed * @param requestedLength The requested length of the data that could not be * read / written Index: src/exceptions/OFRemoveItemFailedException.h ================================================================== --- src/exceptions/OFRemoveItemFailedException.h +++ src/exceptions/OFRemoveItemFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFRemoveItemFailedException \ * OFRemoveItemFailedException.h ObjFW/OFRemoveItemFailedException.h * * @brief An exception indicating that removing an item failed. */ @@ -31,23 +31,23 @@ { OFURL *_URL; int _errNo; } -/*! +/** * @brief The URL of the item which could not be removed. */ @property (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased remove failed exception. * * @param URL The URL of the item which could not be removed * @param errNo The errno of the error that occurred * @return A new, autoreleased remove item failed exception @@ -55,11 +55,11 @@ + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated remove failed exception. * * @param URL The URL of the item which could not be removed * @param errNo The errno of the error that occurred * @return An initialized remove item failed exception Index: src/exceptions/OFResolveHostFailedException.h ================================================================== --- src/exceptions/OFResolveHostFailedException.h +++ src/exceptions/OFResolveHostFailedException.h @@ -18,11 +18,11 @@ #import "OFException.h" #import "OFDNSResolver.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFResolveHostFailedException \ * OFResolveHostFailedException.h ObjFW/OFResolveHostFailedException.h * * @brief An exception indicating that resolving a host failed. */ @@ -31,26 +31,26 @@ OFString *_host; of_socket_address_family_t _addressFamily; of_dns_resolver_error_t _error; } -/*! +/** * @brief The host which could not be resolved. */ @property (readonly, nonatomic) OFString *host; -/*! +/** * @brief The address family for which the host could not be resolved. */ @property (readonly, nonatomic) of_socket_address_family_t addressFamily; -/*! +/** * @brief The error from the resolver. */ @property (readonly, nonatomic) of_dns_resolver_error_t error; -/*! +/** * @brief Creates a new, autoreleased resolve host failed exception. * * @param host The host which could not be resolved * @param addressFamily The address family for which the host could not be * resolved @@ -59,11 +59,11 @@ */ + (instancetype)exceptionWithHost: (OFString *)host addressFamily: (of_socket_address_family_t)addressFamily error: (of_dns_resolver_error_t)error; -/*! +/** * @brief Initializes an already allocated resolve host failed exception. * * @param host The host which could not be resolved * @param addressFamily The address family for which the host could not be * resolved Index: src/exceptions/OFRetrieveItemAttributesFailedException.h ================================================================== --- src/exceptions/OFRetrieveItemAttributesFailedException.h +++ src/exceptions/OFRetrieveItemAttributesFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFRetrieveItemAttributesFailedException \ * OFRetrieveItemAttributesFailedException.h \ * ObjFW/OFRetrieveItemAttributesFailedException.h * * @brief An exception indicating an item's attributes could not be retrieved. @@ -32,23 +32,23 @@ { OFURL *_URL; int _errNo; } -/*! +/** * @brief The URL of the item whose attributes could not be retrieved. */ @property (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased retrieve item attributes failed exception. * * @param URL The URL of the item whose attributes could not be retrieved * @param errNo The errno of the error that occurred * @return A new, autoreleased retrieve item attributes failed exception @@ -56,11 +56,11 @@ + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated retrieve item attributes failed * exception. * * @param URL The URL of the item whose attributes could not be retrieved * @param errNo The errno of the error that occurred Index: src/exceptions/OFSandboxActivationFailedException.h ================================================================== --- src/exceptions/OFSandboxActivationFailedException.h +++ src/exceptions/OFSandboxActivationFailedException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFSandbox; -/*! +/** * @class OFSandboxActivationFailedException \ * OFSandboxActivationFailedException.h \ * ObjFW/OFSandboxActivationFailedException.h * * @brief An exception indicating that sandboxing the process failed. @@ -32,23 +32,23 @@ { OFSandbox *_sandbox; int _errNo; } -/*! +/** * @brief The sandbox which could not be activated. */ @property (readonly, nonatomic) OFSandbox *sandbox; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased sandboxing failed exception. * * @param sandbox The sandbox which could not be activated * @param errNo The errno of the error that occurred * @return A new, autoreleased sandboxing failed exception @@ -56,11 +56,11 @@ + (instancetype)exceptionWithSandbox: (OFSandbox *)sandbox errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated sandboxing failed exception. * * @param sandbox The sandbox which could not be activated * @param errNo The errno of the error that occurred * @return An initialized sandboxing failed exception Index: src/exceptions/OFSeekFailedException.h ================================================================== --- src/exceptions/OFSeekFailedException.h +++ src/exceptions/OFSeekFailedException.h @@ -18,11 +18,11 @@ #import "OFException.h" #import "OFSeekableStream.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSeekFailedException \ * OFSeekFailedException.h ObjFW/OFSeekFailedException.h * * @brief An exception indicating that seeking in a stream failed. */ @@ -31,33 +31,33 @@ OFSeekableStream *_stream; of_offset_t _offset; int _whence, _errNo; } -/*! +/** * @brief The stream for which seeking failed. */ @property (readonly, nonatomic) OFSeekableStream *stream; -/*! +/** * @brief The offset to which seeking failed. */ @property (readonly, nonatomic) of_offset_t offset; -/*! +/** * @brief To what the offset is relative. */ @property (readonly, nonatomic) int whence; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased seek failed exception. * * @param stream The stream for which seeking failed * @param offset The offset to which seeking failed * @param whence To what the offset is relative @@ -69,11 +69,11 @@ whence: (int)whence errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated seek failed exception. * * @param stream The stream for which seeking failed * @param offset The offset to which seeking failed * @param whence To what the offset is relative Index: src/exceptions/OFSetItemAttributesFailedException.h ================================================================== --- src/exceptions/OFSetItemAttributesFailedException.h +++ src/exceptions/OFSetItemAttributesFailedException.h @@ -20,11 +20,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFSetItemAttributesFailedException \ * OFSetItemAttributesFailedException.h \ * ObjFW/OFSetItemAttributesFailedException.h * * @brief An exception indicating an item's attributes could not be set. @@ -35,33 +35,33 @@ of_file_attributes_t _attributes; of_file_attribute_key_t _failedAttribute; int _errNo; } -/*! +/** * @brief The URL of the item whose attributes could not be set. */ @property (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief The attributes that should have been set. */ @property (readonly, nonatomic) of_file_attributes_t attributes; -/*! +/** * @brief The first attribute that could not be set. */ @property (readonly, nonatomic) of_file_attribute_key_t failedAttribute; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased set item attributes failed exception. * * @param URL The URL of the item whose attributes could not be set * @param attributes The attributes that should have been set for the specified * item. @@ -74,11 +74,11 @@ failedAttribute: (of_file_attribute_key_t)failedAttribute errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated set item attributes failed exception. * * @param URL The URL of the item whose attributes could not be set * @param attributes The attributes that should have been set for the specified * item. Index: src/exceptions/OFSetOptionFailedException.h ================================================================== --- src/exceptions/OFSetOptionFailedException.h +++ src/exceptions/OFSetOptionFailedException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSetOptionFailedException \ * OFSetOptionFailedException.h ObjFW/OFSetOptionFailedException.h * * @brief An exception indicating that setting an option for an object failed. */ @@ -29,23 +29,23 @@ { id _object; int _errNo; } -/*! +/** * @brief The object for which the option could not be set. */ @property (readonly, nonatomic) id object; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased set option failed exception. * * @param object The object for which the option could not be set * @param errNo The errno of the error that occurred * @return A new, autoreleased set option failed exception @@ -53,11 +53,11 @@ + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated set option failed exception. * * @param object The object for which the option could not be set * @param errNo The errno of the error that occurred * @return An initialized set option failed exception Index: src/exceptions/OFSetWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFSetWindowsRegistryValueFailedException.h +++ src/exceptions/OFSetWindowsRegistryValueFailedException.h @@ -20,11 +20,11 @@ #include OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFSetWindowsRegistryValueFailedException \ * OFSetWindowsRegistryValueFailedException.h \ * ObjFW/OFSetWindowsRegistryValueFailedException.h * * @brief An exception indicating that setting a Windows registry value failed. @@ -36,36 +36,36 @@ OFData *_Nullable _data; DWORD _type; LSTATUS _status; } -/*! +/** * @brief The registry key on which setting the value failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; -/*! +/** * @brief The value which could not be set. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; -/*! +/** * @brief The data to which the value could not be set. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFData *data; -/*! +/** * @brief The type for the value that could not be set. */ @property (readonly, nonatomic) DWORD type; -/*! +/** * @brief The status returned by RegSetValueEx(). */ @property (readonly, nonatomic) LSTATUS status; -/*! +/** * @brief Creates a new, autoreleased set Windows registry value failed * exception. * * @param registryKey The registry key on which setting the value failed * @param value The value which could not be set @@ -80,11 +80,11 @@ type: (DWORD)type status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated set Windows registry value failed * exception. * * @param registryKey The registry key on which setting the value failed * @param value The value which could not be set Index: src/exceptions/OFStillLockedException.h ================================================================== --- src/exceptions/OFStillLockedException.h +++ src/exceptions/OFStillLockedException.h @@ -18,11 +18,11 @@ #import "OFException.h" #import "OFLocking.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFStillLockedException \ * OFStillLockedException.h ObjFW/OFStillLockedException.h * * @brief An exception indicating that a lock is still locked. */ @@ -29,24 +29,24 @@ @interface OFStillLockedException: OFException { id _lock; } -/*! +/** * @brief The lock which is still locked. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id lock; -/*! +/** * @brief Creates a new, autoreleased still locked exception. * * @param lock The lock which is still locked * @return A new, autoreleased still locked exception */ + (instancetype)exceptionWithLock: (nullable id )lock; -/*! +/** * @brief Initializes an already allocated still locked exception. * * @param lock The lock which is still locked * @return An initialized still locked exception */ Index: src/exceptions/OFStillLockedException.m ================================================================== --- src/exceptions/OFStillLockedException.m +++ src/exceptions/OFStillLockedException.m @@ -52,11 +52,11 @@ - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"Deallocation of a lock of type %@ even though it was " - @"still locked!", _lock.class]; + @"still locked!", [_lock class]]; else return @"Deallocation of a lock even though it was still " @"locked!"; } @end Index: src/exceptions/OFThreadJoinFailedException.h ================================================================== --- src/exceptions/OFThreadJoinFailedException.h +++ src/exceptions/OFThreadJoinFailedException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFThread; -/*! +/** * @class OFThreadJoinFailedException \ * OFThreadJoinFailedException.h ObjFW/OFThreadJoinFailedException.h * * @brief An exception indicating that joining a thread failed. */ @@ -35,31 +35,31 @@ { OFThread *_thread; int _errNo; } -/*! +/** * @brief The thread which could not be joined. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThread *thread; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Creates a new, autoreleased thread join failed exception. * * @param thread The thread which could not be joined * @param errNo The errno of the error that occurred * @return A new, autoreleased thread join failed exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated thread join failed exception. * * @param thread The thread which could not be joined * @param errNo The errno of the error that occurred * @return An initialized thread join failed exception Index: src/exceptions/OFThreadStartFailedException.h ================================================================== --- src/exceptions/OFThreadStartFailedException.h +++ src/exceptions/OFThreadStartFailedException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFThread; -/*! +/** * @class OFThreadStartFailedException \ * OFThreadStartFailedException.h ObjFW/OFThreadStartFailedException.h * * @brief An exception indicating that starting a thread failed. */ @@ -35,31 +35,31 @@ { OFThread *_thread; int _errNo; } -/*! +/** * @brief The thread which could not be started. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThread *thread; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Creates a new, autoreleased thread start failed exception. * * @param thread The thread which could not be started * @param errNo The errno of the error that occurred * @return A new, autoreleased thread start failed exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated thread start failed exception. * * @param thread The thread which could not be started * @param errNo The errno of the error that occurred * @return An initialized thread start failed exception Index: src/exceptions/OFThreadStillRunningException.h ================================================================== --- src/exceptions/OFThreadStillRunningException.h +++ src/exceptions/OFThreadStillRunningException.h @@ -23,11 +23,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFThread; -/*! +/** * @class OFThreadStillRunningException \ * OFThreadStillRunningException.h ObjFW/OFThreadStillRunningException.h * * @brief An exception indicating that a thread is still running. */ @@ -34,24 +34,24 @@ @interface OFThreadStillRunningException: OFException { OFThread *_thread; } -/*! +/** * @brief The thread which is still running. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThread *thread; -/*! +/** * @brief Creates a new, autoreleased thread still running exception. * * @param thread The thread which is still running * @return A new, autoreleased thread still running exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread; -/*! +/** * @brief Initializes an already allocated thread still running exception. * * @param thread The thread which is still running * @return An initialized thread still running exception */ Index: src/exceptions/OFTruncatedDataException.h ================================================================== --- src/exceptions/OFTruncatedDataException.h +++ src/exceptions/OFTruncatedDataException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFTruncatedDataException \ * OFTruncatedDataException.h ObjFW/OFTruncatedDataException.h * * @brief An exception indicating that data was truncated while it should not * have been truncated. Index: src/exceptions/OFUnboundNamespaceException.h ================================================================== --- src/exceptions/OFUnboundNamespaceException.h +++ src/exceptions/OFUnboundNamespaceException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFXMLElement; -/*! +/** * @class OFUnboundNamespaceException \ * OFUnboundNamespaceException.h ObjFW/OFUnboundNamespaceException.h * * @brief An exception indicating an attempt to use an unbound namespace. */ @@ -31,27 +31,27 @@ { OFString *_namespace; OFXMLElement *_element; } -/*! +/** * @brief The unbound namespace. */ #ifndef __cplusplus @property (readonly, nonatomic) OFString *namespace; #else @property (readonly, nonatomic, getter=namespace) OFString *namespace_; #endif -/*! +/** * @brief The element in which the namespace was not bound. */ @property (readonly, nonatomic) OFXMLElement *element; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased unbound namespace exception. * * @param namespace_ The namespace which is unbound * @param element The element in which the namespace was not bound * @return A new, autoreleased unbound namespace exception @@ -59,11 +59,11 @@ + (instancetype)exceptionWithNamespace: (OFString *)namespace_ element: (OFXMLElement *)element; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated unbound namespace exception. * * @param namespace_ The namespace which is unbound * @param element The element in which the namespace was not bound * @return An initialized unbound namespace exception Index: src/exceptions/OFUnboundPrefixException.h ================================================================== --- src/exceptions/OFUnboundPrefixException.h +++ src/exceptions/OFUnboundPrefixException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFXMLParser; -/*! +/** * @class OFUnboundPrefixException \ * OFUnboundPrefixException.h ObjFW/OFUnboundPrefixException.h * * @brief An exception indicating an attempt to use an unbound prefix. */ @@ -31,23 +31,23 @@ { OFString *_prefix; OFXMLParser *_parser; } -/*! +/** * @brief The unbound prefix. */ @property (readonly, nonatomic) OFString *prefix; -/*! +/** * @brief The parser which encountered the unbound prefix. */ @property (readonly, nonatomic) OFXMLParser *parser; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased unbound prefix exception. * * @param prefix The prefix which is unbound * @param parser The parser which encountered the unbound prefix * @return A new, autoreleased unbound prefix exception @@ -55,11 +55,11 @@ + (instancetype)exceptionWithPrefix: (OFString *)prefix parser: (OFXMLParser *)parser; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated unbound prefix exception. * * @param prefix The prefix which is unbound * @param parser The parser which encountered the unbound prefix * @return An initialized unbound prefix exception Index: src/exceptions/OFUndefinedKeyException.h ================================================================== --- src/exceptions/OFUndefinedKeyException.h +++ src/exceptions/OFUndefinedKeyException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFUndefinedKeyException \ * OFUndefinedKeyException.h ObjFW/OFUndefinedKeyException.h * * @brief An exception indicating that a key is undefined (e.g. for Key Value * Coding). @@ -31,28 +31,28 @@ id _object; OFString *_key; id _Nullable _value; } -/*! +/** * @brief The object on which the key is undefined. */ @property (readonly, nonatomic) id object; -/*! +/** * @brief The key which is undefined. */ @property (readonly, nonatomic) OFString *key; -/*! +/** * @brief The value for the undefined key */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id value; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * @@ -59,11 +59,11 @@ * @return A new, autoreleased undefined key exception */ + (instancetype)exceptionWithObject: (id)object key: (OFString *)key; -/*! +/** * @brief Creates a new, autoreleased undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * @param value The value for the undefined key @@ -74,11 +74,11 @@ key: (OFString *)key value: (nullable id)value; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * @@ -85,11 +85,11 @@ * @return An initialized undefined key exception */ - (instancetype)initWithObject: (id)object key: (OFString *)key; -/*! +/** * @brief Initializes an already allocated undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * @param value The value for the undefined key Index: src/exceptions/OFUnknownXMLEntityException.h ================================================================== --- src/exceptions/OFUnknownXMLEntityException.h +++ src/exceptions/OFUnknownXMLEntityException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFUnknownXMLEntityException \ * OFUnknownXMLEntityException.h ObjFW/OFUnknownXMLEntityException.h * * @brief An exception indicating that a parser encountered an unknown XML * entity. @@ -29,26 +29,26 @@ @interface OFUnknownXMLEntityException: OFException { OFString *_entityName; } -/*! +/** * @brief The name of the unknown XML entity. */ @property (readonly, nonatomic) OFString *entityName; -/*! +/** * @brief Creates a new, autoreleased unknown XML entity exception. * * @param entityName The name of the unknown XML entity * @return A new, autoreleased unknown XML entity exception */ + (instancetype)exceptionWithEntityName: (OFString *)entityName; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated unknown XML entity exception. * * @param entityName The name of the unknown XML entity * @return An initialized unknown XML entity exception */ Index: src/exceptions/OFUnlockFailedException.h ================================================================== --- src/exceptions/OFUnlockFailedException.h +++ src/exceptions/OFUnlockFailedException.h @@ -18,11 +18,11 @@ #import "OFException.h" #import "OFLocking.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFUnlockFailedException \ * OFUnlockFailedException.h ObjFW/OFUnlockFailedException.h * * @brief An exception indicating that unlocking a lock failed. */ @@ -30,31 +30,31 @@ { id _lock; int _errNo; } -/*! +/** * @brief The lock which could not be unlocked. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id lock; -/*! +/** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; -/*! +/** * @brief Creates a new, autoreleased unlock failed exception. * * @param lock The lock which could not be unlocked * @param errNo The errno of the error that occurred * @return A new, autoreleased unlock failed exception */ + (instancetype)exceptionWithLock: (nullable id )lock errNo: (int)errNo; -/*! +/** * @brief Initializes an already allocated unlock failed exception. * * @param lock The lock which could not be unlocked * @param errNo The errno of the error that occurred * @return An initialized unlock failed exception Index: src/exceptions/OFUnlockFailedException.m ================================================================== --- src/exceptions/OFUnlockFailedException.m +++ src/exceptions/OFUnlockFailedException.m @@ -57,8 +57,8 @@ - (OFString *)description { return [OFString stringWithFormat: @"A lock of type %@ could not be unlocked: %s", - _lock.class, strerror(_errNo)]; + [_lock class], strerror(_errNo)]; } @end Index: src/exceptions/OFUnsupportedProtocolException.h ================================================================== --- src/exceptions/OFUnsupportedProtocolException.h +++ src/exceptions/OFUnsupportedProtocolException.h @@ -19,11 +19,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFURL; -/*! +/** * @class OFUnsupportedProtocolException \ * OFUnsupportedProtocolException.h \ * ObjFW/OFUnsupportedProtocolException.h * * @brief An exception indicating that the protocol specified by the URL is not @@ -32,28 +32,28 @@ @interface OFUnsupportedProtocolException: OFException { OFURL *_URL; } -/*! +/** * @brief The URL whose protocol is unsupported. */ @property (readonly, nonatomic) OFURL *URL; -/*! +/** * @brief Creates a new, autoreleased unsupported protocol exception. * * @param URL The URL whose protocol is unsupported * @return A new, autoreleased unsupported protocol exception */ + (instancetype)exceptionWithURL: (OFURL*)URL; -/*! +/** * @brief Initializes an already allocated unsupported protocol exception * * @param URL The URL whose protocol is unsupported * @return An initialized unsupported protocol exception */ - (instancetype)initWithURL: (OFURL*)URL OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFUnsupportedVersionException.h ================================================================== --- src/exceptions/OFUnsupportedVersionException.h +++ src/exceptions/OFUnsupportedVersionException.h @@ -17,11 +17,11 @@ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFUnsupportedVersionException \ * OFUnsupportedVersionException.h ObjFW/OFUnsupportedVersionException.h * * @brief An exception indicating that the specified version of the format or * protocol is not supported. @@ -29,32 +29,32 @@ @interface OFUnsupportedVersionException: OFException { OFString *_version; } -/*! +/** * @brief The version which is unsupported. */ @property (readonly, nonatomic) OFString *version; + (instancetype)exception OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased unsupported version exception. * * @param version The version which is unsupported * @return A new, autoreleased unsupported version exception */ + (instancetype)exceptionWithVersion: (OFString *)version; - (instancetype)init OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated unsupported protocol exception. * * @param version The version which is unsupported * @return An initialized unsupported version exception */ - (instancetype)initWithVersion: (OFString *)version OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFWriteFailedException.h ================================================================== --- src/exceptions/OFWriteFailedException.h +++ src/exceptions/OFWriteFailedException.h @@ -17,11 +17,11 @@ #import "OFReadOrWriteFailedException.h" OF_ASSUME_NONNULL_BEGIN -/*! +/** * @class OFWriteFailedException \ * OFWriteFailedException.h ObjFW/OFWriteFailedException.h * * @brief An exception indicating that writing to an object failed. */ @@ -28,11 +28,11 @@ @interface OFWriteFailedException: OFReadOrWriteFailedException { size_t _bytesWritten; } -/*! +/** * @brief The number of bytes already written before the write failed. * * This can be used to make sure that a retry does not write data already * written before. */ @@ -40,11 +40,11 @@ + (instancetype)exceptionWithObject: (id)object requestedLength: (size_t)requestedLength errNo: (int)errNo OF_UNAVAILABLE; -/*! +/** * @brief Creates a new, autoreleased write failed exception. * * @param object The object from which reading or to which writing failed * @param requestedLength The requested length of the data that could not be * read / written @@ -60,11 +60,11 @@ - (instancetype)initWithObject: (id)object requestedLength: (size_t)requestedLength errNo: (int)errNo OF_UNAVAILABLE; -/*! +/** * @brief Initializes an already allocated write failed exception. * * @param object The object from which reading or to which writing failed * @param requestedLength The requested length of the data that could not be * read / written Index: src/forwarding/forwarding-powerpc-elf.S ================================================================== --- src/forwarding/forwarding-powerpc-elf.S +++ src/forwarding/forwarding-powerpc-elf.S @@ -25,10 +25,17 @@ .section .text of_forward: stwu %r1, -112(%r1) mflr %r0 stw %r0, 116(%r1) + stw %r30, 104(%r1) + + bl 0f +0: + mflr %r30 + addis %r30, %r30, .Lbiased_got2-0b@ha + addi %r30, %r30, .Lbiased_got2-0b@l /* Save all arguments */ stw %r3, 8(%r1) stw %r4, 12(%r1) stw %r5, 16(%r1) @@ -46,28 +53,25 @@ stfd %f5, 72(%r1) stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) - bl object_getClass@plt + bl object_getClass+0x8000@plt - lis %r4, sel_forwardingTargetForSelector_@ha - la %r4, sel_forwardingTargetForSelector_@l(%r4) - bl class_respondsToSelector@plt + lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) + bl class_respondsToSelector+0x8000@plt cmpwi %r3, 0 beq- 0f lwz %r3, 8(%r1) - lis %r4, sel_forwardingTargetForSelector_@ha - la %r4, sel_forwardingTargetForSelector_@l(%r4) - bl objc_msg_lookup@plt + lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) + bl objc_msg_lookup+0x8000@plt mtctr %r3 lwz %r3, 8(%r1) - lis %r4, sel_forwardingTargetForSelector_@ha - la %r4, sel_forwardingTargetForSelector_@l(%r4) + lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) lwz %r5, 12(%r1) bctrl cmpwi %r3, 0 beq- 0f @@ -76,11 +80,11 @@ beq- 0f stw %r3, 8(%r1) lwz %r4, 12(%r1) - bl objc_msg_lookup@plt + bl objc_msg_lookup+0x8000@plt mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) @@ -99,31 +103,42 @@ lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) + lwz %r30, 104(%r1) lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) + lwz %r0, .Lgot_of_method_not_found-.Lbiased_got2(%r30) + mtctr %r0 + lwz %r30, 104(%r1) lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 - b of_method_not_found@plt + bctr .type of_forward, @function .size of_forward, .-of_forward of_forward_stret: stwu %r1, -112(%r1) mflr %r0 stw %r0, 116(%r1) + stw %r30, 104(%r1) + + bl 0f +0: + mflr %r30 + addis %r30, %r30, .Lbiased_got2-0b@ha + addi %r30, %r30, .Lbiased_got2-0b@l /* Save all arguments */ stw %r3, 8(%r1) stw %r4, 12(%r1) stw %r5, 16(%r1) @@ -142,28 +157,25 @@ stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) mr %r3, %r4 - bl object_getClass@plt + bl object_getClass+0x800@plt - lis %r4, sel_forwardingTargetForSelector_@ha - la %r4, sel_forwardingTargetForSelector_@l(%r4) - bl class_respondsToSelector@plt + lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) + bl class_respondsToSelector+0x8000@plt cmpwi %r3, 0 beq- 0f lwz %r3, 12(%r1) - lis %r4, sel_forwardingTargetForSelector_@ha - la %r4, sel_forwardingTargetForSelector_@l(%r4) - bl objc_msg_lookup@plt + lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) + bl objc_msg_lookup+0x8000@plt mtctr %r3 lwz %r3, 12(%r1) - lis %r4, sel_forwardingTargetForSelector_@ha - la %r4, sel_forwardingTargetForSelector_@l(%r4) + lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) lwz %r5, 16(%r1) bctrl cmpwi %r3, 0 beq- 0f @@ -172,11 +184,11 @@ beq- 0f stw %r3, 12(%r1) lwz %r4, 16(%r1) - bl objc_msg_lookup_stret@plt + bl objc_msg_lookup_stret+0x8000@plt mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) @@ -204,23 +216,42 @@ 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) + lwz %r0, .Lgot_of_method_not_found_stret-.Lbiased_got2(%r30) + mtctr %r0 + lwz %r30, 104(%r1) lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 - b of_method_not_found_stret@plt + bctr .type of_forward_stret, @function .size of_forward_stret, .-of_forward_stret init: - lis %r3, module@ha - la %r3, module@l(%r3) - b __objc_exec_class@plt + stwu %r1, -16(%r1) + mflr %r0 + stw %r0, 20(%r1) + stw %r30, 8(%r1) + + bl 0f +0: + mflr %r30 + addis %r30, %r30, .Lbiased_got2-0b@ha + addi %r30, %r30, .Lbiased_got2-0b@l + + lwz %r3, .Lgot_module-.Lbiased_got2(%r30) + bl __objc_exec_class+0x8000@plt + + lwz %r30, 8(%r1) + lwz %r0, 20(%r1) + addi %r1, %r1, 16 + mtlr %r0 + blr .section .ctors, "aw", @progbits .long init .section .rodata @@ -237,8 +268,19 @@ .long 0 .long 0 module: .long 8, 16, 0, symtab +.section .got2, "aw" +.Lbiased_got2 = .+0x8000 +.Lgot_module: + .long module +.Lgot_sel_forwardingTargetForSelector_: + .long sel_forwardingTargetForSelector_ +.Lgot_of_method_not_found: + .long of_method_not_found +.Lgot_of_method_not_found_stret: + .long of_method_not_found_stret + #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif Index: src/forwarding/forwarding-sparc-elf.S ================================================================== --- src/forwarding/forwarding-sparc-elf.S +++ src/forwarding/forwarding-sparc-elf.S @@ -24,39 +24,47 @@ .section .text of_forward: save %sp, -96, %sp +#ifdef OF_PIC sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 +#endif mov %i0, %o0 call object_getClass nop sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 +#ifdef OF_PIC ld [%l7 + %o1], %o1 +#endif call class_respondsToSelector nop cmp %o0, 0 be 0f mov %i0, %o0 sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 +#ifdef OF_PIC ld [%l7 + %o1], %o1 +#endif call objc_msg_lookup nop mov %o0, %l0 mov %i0, %o0 sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 +#ifdef OF_PIC ld [%l7 + %o1], %o1 +#endif jmpl %l0, %o7 mov %i1, %o2 cmp %o0, 0 be 0f @@ -77,39 +85,47 @@ .size of_forward, .-of_forward of_forward_stret: save %sp, -96, %sp +#ifdef OF_PIC sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 +#endif mov %i1, %o0 call object_getClass nop sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 +#ifdef OF_PIC ld [%l7 + %o1], %o1 +#endif call class_respondsToSelector nop cmp %o0, 0 be 0f mov %i1, %o0 sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 +#ifdef OF_PIC ld [%l7 + %o1], %o1 +#endif call objc_msg_lookup nop mov %o0, %l0 mov %i1, %o0 sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 +#ifdef OF_PIC ld [%l7 + %o1], %o1 +#endif jmpl %l0, %o7 mov %i2, %o2 cmp %o0, 0 be 0f @@ -130,24 +146,30 @@ .size of_forward_stret, .-of_forward_stret init: save %sp, -96, %sp +#ifdef OF_PIC sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 +#endif sethi %hi(module), %i0 or %i0, %lo(module), %i0 +#ifdef OF_PIC ld [%l7 + %i0], %i0 +#endif call __objc_exec_class restore +#ifdef OF_PIC add_pc: jmp %o7 + 8 add %l7, %o7, %l7 +#endif #ifdef OF_SOLARIS .section .init_array, "aw" #else .section .ctors, "aw", %progbits Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -134,15 +134,15 @@ #if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__)) # define OF_HAVE_NONFRAGILE_IVARS #endif #ifdef OF_HAVE_NONFRAGILE_IVARS -# define OF_RESERVE_IVARS(num) +# define OF_RESERVE_IVARS(cls, num) #else -# define OF_RESERVE_IVARS(num) \ +# define OF_RESERVE_IVARS(cls, num) \ @private \ - void *OF_PREPROCESSOR_CONCAT(_reserved, __COUNTER__)[num]; + void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num]; #endif #ifdef __GNUC__ # define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #else @@ -415,17 +415,17 @@ } \ \ abort(); #endif #ifdef __clang__ -# define OF_DEALLOC_UNSUPPORTED \ - [self doesNotRecognizeSelector: _cmd]; \ - \ - abort(); \ - \ - _Pragma("clang diagnostic push ignore \"-Wunreachable-code\""); \ - [super dealloc]; /* Get rid of a stupid warning */ \ +# define OF_DEALLOC_UNSUPPORTED \ + [self doesNotRecognizeSelector: _cmd]; \ + \ + abort(); \ + \ + _Pragma("clang diagnostic push ignored \"-Wunreachable-code\""); \ + [super dealloc]; /* Get rid of a stupid warning */ \ _Pragma("clang diagnostic pop"); #else # define OF_DEALLOC_UNSUPPORTED \ [self doesNotRecognizeSelector: _cmd]; \ \ @@ -896,27 +896,6 @@ static OF_INLINE char of_ascii_tolower(char c) { return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c); } - -/* This does *NOT* provide cryptographically secure randomness! */ -static OF_INLINE uint32_t -of_random(void) { -#if defined(OF_HAVE_ARC4RANDOM) - return arc4random(); -#elif defined(OF_HAVE_RANDOM) - struct timeval tv; - - gettimeofday(&tv, NULL); - srandom((unsigned)(tv.tv_sec ^ tv.tv_usec)); - return (((uint32_t)(random()) << 16) | ((uint32_t)(random()) & 0xFFFF)); -#else - struct timeval tv; - - gettimeofday(&tv, NULL); - srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); - return (((uint32_t)(rand()) << 16) | ((uint32_t)(rand()) & 0xFFFF)); -#endif -} - #endif Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -2,11 +2,10 @@ #undef LLONG_MAX #undef LLONG_MIN #undef OF_APPLE_RUNTIME #undef OF_BIG_ENDIAN #undef OF_FLOAT_BIG_ENDIAN -#undef OF_HAVE_ARC4RANDOM #undef OF_HAVE_ATOMIC_BUILTINS #undef OF_HAVE_ATOMIC_OPS #undef OF_HAVE_BUILTIN_BSWAP16 #undef OF_HAVE_BUILTIN_BSWAP32 #undef OF_HAVE_BUILTIN_BSWAP64 @@ -29,11 +28,10 @@ #undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_PROCESSES #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS -#undef OF_HAVE_RANDOM #undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SOCKETS #undef OF_HAVE_STDNORETURN #undef OF_HAVE_SYMLINK Index: src/pbkdf2.h ================================================================== --- src/pbkdf2.h +++ src/pbkdf2.h @@ -24,46 +24,46 @@ #import "macros.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFHMAC; -/*! +/** * @brief The parameters for @ref of_pbkdf2. */ typedef struct of_pbkdf2_parameters_t { - /*! @brief The HMAC to use to derive a key. */ + /** @brief The HMAC to use to derive a key. */ OFHMAC *HMAC; - /*! @brief The number of iterations to perform. */ + /** @brief The number of iterations to perform. */ size_t iterations; - /*! @brief The salt to derive a key with. */ + /** @brief The salt to derive a key with. */ const unsigned char *salt; - /*! @brief The length of the salt. */ + /** @brief The length of the salt. */ size_t saltLength; - /*! @brief The password to derive a key from. */ + /** @brief The password to derive a key from. */ const char *password; - /*! @brief The length of the password. */ + /** @brief The length of the password. */ size_t passwordLength; - /*! @brief The buffer to write the key to. */ + /** @brief The buffer to write the key to. */ unsigned char *key; - /*! + /** * @brief The desired length for the derived key. * * @ref key needs to have enough storage. */ size_t keyLength; - /*! @brief Whether data may be stored in swappable memory. */ + /** @brief Whether data may be stored in swappable memory. */ bool allowsSwappableMemory; } of_pbkdf2_parameters_t; #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief Derives a key from a password and a salt using PBKDF2. * * @note This will call @ref OFHMAC::reset on the `HMAC` first, making it * possible to reuse the `HMAC`, but also meaning all previous results * from the `HMAC` get invalidated if they have not been copied. Index: src/platform/posix/condition.m ================================================================== --- src/platform/posix/condition.m +++ src/platform/posix/condition.m @@ -48,15 +48,15 @@ of_time_interval_t timeout) { struct timespec ts; ts.tv_sec = (time_t)timeout; - ts.tv_nsec = (timeout - ts.tv_sec) * 1000000000; + ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000); return (pthread_cond_timedwait(condition, mutex, &ts) == 0); } bool of_condition_free(of_condition_t *condition) { return (pthread_cond_destroy(condition) == 0); } ADDED src/runtime/Info.plist.in Index: src/runtime/Info.plist.in ================================================================== --- src/runtime/Info.plist.in +++ src/runtime/Info.plist.in @@ -0,0 +1,22 @@ + + + + + CFBundleExecutable + ObjFWRT + CFBundleName + ObjFWRT + CFBundleIdentifier + im.nil.objfw.rt + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleVersion + @BUNDLE_VERSION@ + CFBundleShortVersionString + @BUNDLE_SHORT_VERSION@ + MinimumOSVersion + 9.0 + + Index: src/runtime/Makefile ================================================================== --- src/runtime/Makefile +++ src/runtime/Makefile @@ -8,10 +8,11 @@ amiga-glue.amigalib.o \ amiga-library-functable.inc \ amiga-library.amigalib.dep \ amiga-library.amigalib.o \ inline.h +DISTCLEAN = Info.plist SHARED_LIB = ${OBJFWRT_SHARED_LIB} STATIC_LIB = ${OBJFWRT_STATIC_LIB} FRAMEWORK = ${OBJFWRT_FRAMEWORK} AMIGA_LIB = ${OBJFWRT_AMIGA_LIB} @@ -35,10 +36,11 @@ protocol.m \ selector.m \ sparsearray.m \ static-instances.m \ synchronized.m \ + tagged-pointer.m \ ${USE_SRCS_THREADS} SRCS_THREADS = threading.m \ ../mutex.m \ ../once.m \ ../tlskey.m Index: src/runtime/ObjFWRT.h ================================================================== --- src/runtime/ObjFWRT.h +++ src/runtime/ObjFWRT.h @@ -26,10 +26,12 @@ #endif #include #include #include + +/** @file */ #ifndef __has_feature # define __has_feature(x) 0 #endif @@ -51,123 +53,121 @@ #if !__has_feature(objc_arc) && !defined(__unsafe_unretained) # define __unsafe_unretained #endif -/*! +/** * @brief A value representing no class. */ #define Nil (Class _Null_unspecified)0 -/*! +/** * @brief A value representing no object. */ #define nil (id _Null_unspecified)0 -/*! +/** * @brief An Objective-C boolean representing true. * * @note This is a legacy from before C had a boolean type. Prefer the standard * C99 true instead! */ #define YES true -/*! +/** * @brief An Objective-C boolean representing false. * * @note This is a legacy from before C had a boolean type. Prefer the standard * C99 false instead! */ #define NO false -/*! @file */ - -/*! +/** * @brief A pointer to a class. */ typedef struct objc_class *Class; -/*! +/** * @brief A pointer to any object. */ typedef struct objc_object *id; -/*! +/** * @brief A selector. * * A selector is the name of a method including the colons and an optional type * encoding. */ typedef const struct objc_selector *SEL; -/*! +/** * @brief A method. * * A method consists of a selector with a type encoding and an implementation. */ typedef const struct objc_method *Method; -/*! +/** * @brief A protocol. */ #if defined(__OBJC__) && !defined(DOXYGEN) @class Protocol; #else typedef const struct objc_protocol *Protocol; #endif -/*! +/** * @brief An instance variable. */ typedef const struct objc_ivar *Ivar; -/*! +/** * @brief A property. */ typedef const struct objc_property *objc_property_t; #if !defined(__wii__) && !defined(__amigaos__) -/*! +/** * @brief An Objective-C boolean. Either @ref YES or @ref NO. * * @note This is a legacy from before C had a boolean type. Prefer the standard * C99 bool instead! */ typedef bool BOOL; #endif -/*! +/** * @brief A method implemenation. * * @param object The messaged object * @param selector The selector sent */ typedef id _Nullable (*IMP)(id _Nonnull object, SEL _Nonnull selector, ...); -/*! +/** * @brief A handler for uncaught exceptions. * * @param exception The exception which was not caught. */ typedef void (*objc_uncaught_exception_handler_t)(id _Nullable exception); -/*! +/** * @brief A handler for mutation during enumeration. * * @param object The object that was mutated during enumeration */ typedef void (*objc_enumeration_mutation_handler_t)(id _Nonnull object); -/*! +/** * @brief A struct representing a call to super. */ struct objc_super { - /*! + /** * @brief The object on which to perform the super call. */ id __unsafe_unretained _Nullable self; - /*! + /** * @brief The class from which to take the method. */ #ifdef __cplusplus Class _Nonnull class_; #else @@ -176,77 +176,480 @@ }; #ifdef __cplusplus extern "C" { #endif + +/** + * @brief Registers a selector with the specified name with the runtime. + * + * @param name The name for the selector to register + * @return The registered selector + */ extern SEL _Nonnull sel_registerName(const char *_Nonnull name); + +/** + * @brief Returns the name of the specified selector. + * + * @param selector The selector whose name should be returned + * @return The name of the specified selector + */ extern const char *_Nonnull sel_getName(SEL _Nonnull selector); + +/** + * @brief Checks two selectors for equality. + * + * Selectors are considered equal if they have the same name - any type + * encoding is ignored. + * + * @param selector1 The first selector + * @param selector2 The second selector + * @return Whether the two selectors are equal + */ extern bool sel_isEqual(SEL _Nonnull selector1, SEL _Nonnull selector2); + +/** + * @brief Allocates a new class and its metaclass. + * + * @param superclass The superclass for the new class + * @param name The name for the new class + * @param extraBytes Extra bytes to add to the instance size + * @return A new, unregistered class pair + */ extern Class _Nonnull objc_allocateClassPair(Class _Nullable superclass, const char *_Nonnull name, size_t extraBytes); + +/** + * @brief Registers an already allocated class pair. + * + * @param class_ The class pair to register + */ extern void objc_registerClassPair(Class _Nonnull class_); + +/** + * @brief Gets the list of all classes known to the runtime. + * + * @param buffer An array of Class to write to. If the buffer does not have + * enough space, the result is truncated. + * @param count The number of classes for which there is space in `buffer` + * @return The number of classes written + */ extern unsigned int objc_getClassList(Class _Nonnull *_Nullable buffer, unsigned int count); + +/** + * @brief Copies the list of all classes known to the runtime. + * + * This is like @ref objc_getClassList, but allocates a buffer large enough for + * all classes. + * + * @param length An optional pointer to an `unsigned int` that will be set to + * the number of classes returned + * @return An array of classes, terminated by `Nil`. You need to call `free()` + * on it when done. + */ extern Class _Nonnull *_Nonnull objc_copyClassList( unsigned int *_Nullable length); + +/** + * @brief Returns whether the specified class is a metaclass. + * + * @param class_ The class which should be examined + * @return Whether the specified class is a metaclass + */ extern bool class_isMetaClass(Class _Nullable class_); + +/** + * @brief Returns the name of the specified class. + * + * @param class_ The class whose name should be returned + * @return The name of the specified class + */ extern const char *_Nullable class_getName(Class _Nullable class_); + +/** + * @brief Returns the superclass of the specified class. + * + * @param class_ The class whose superclass should be returned + * @return The superclass of the specified class + */ extern Class _Nullable class_getSuperclass(Class _Nullable class_); + +/** + * @brief Returns the instance size of the specified class. + * + * @param class_ The class whose instance size should be returned + * @return The instance size of the specified class + */ extern unsigned long class_getInstanceSize(Class _Nullable class_); + +/** + * @brief Returns whether the specified class responds to the specified + * selector. + * + * @param class_ The class which should be examined + * @param selector The selector which should be checked + * @return Whether the specified class responds to the specified selector + */ extern bool class_respondsToSelector(Class _Nullable class_, SEL _Nonnull selector); + +/** + * @brief Returns whether the specified class conforms to the specified + * protocol. + * + * @param class_ The class which should be examined + * @param protocol The protocol for which conformance should be checked + * @return Whether the specified class conforms to the specified protocol + */ extern bool class_conformsToProtocol(Class _Nullable class_, Protocol *_Nonnull protocol); + +/** + * @brief Returns the class's method implementation for the specified selector. + * + * @warning If the method uses the struct return ABI, you need to use + * @ref class_getMethodImplementation_stret instead! Depending on the + * ABI, small structs might not use the struct return ABI. + * + * @param class_ The class whose method implementation should be returned + * @param selector The selector for the method whose implementation should be + * returned + * @return The class's metod implementation for the specified selector + */ extern IMP _Nullable class_getMethodImplementation(Class _Nullable class_, SEL _Nonnull selector); + +/** + * @brief Returns the class's method implementation for the specified selector. + * + * @warning If the method does not use use the struct return ABI, you need to + * use @ref class_getMethodImplementation instead! Depending on the + * ABI, small structs might not use the struct return ABI. + * + * @param class_ The class whose method implementation should be returned + * @param selector The selector for the method whose implementation should be + * returned + * @return The class's metod implementation for the specified selector + */ extern IMP _Nullable class_getMethodImplementation_stret(Class _Nullable class_, SEL _Nonnull selector); + +/** + * @brief Returns the class's instance method for the specified selector + * + * @param class_ The class whose instance method should be returned + * @param selector The selector of the instance method to return + * @return The class's instance method for the specified selector + */ extern Method _Nullable class_getInstanceMethod(Class _Nullable class_, SEL _Nonnull selector); + +/** + * @brief Adds the specified method to the class. + * + * @param class_ The class to which to add the method + * @param selector The selector for the method to add + * @param implementation The implementation of the method to add + * @param typeEncoding The type encoding of the method to add + * @return Whether the specified method was added + */ extern bool class_addMethod(Class _Nonnull class_, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding); + +/** + * @brief Replaces or adds the specified method of the class. + * + * @param class_ The class to which to replace the method + * @param selector The selector for the method to replace + * @param implementation The implementation of the method to replace + * @param typeEncoding The type encoding of the method to replace. Only used if + * the method does not exist yet. + * @return The old implementation of the method + */ extern IMP _Nullable class_replaceMethod(Class _Nonnull class_, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding); + +/** + * @brief Returns the object's class. + * + * @param object The object whose class should be returned + * @return The object's class + */ extern Class _Nullable object_getClass(id _Nullable object); + +/** + * @brief Sets the object's class. + * + * This can be used to swizzle an object's class. + * + * @param object The object whose class should be set + * @param class_ The new class for the object + * @return The old class of the object + */ extern Class _Nullable object_setClass(id _Nullable object, Class _Nonnull class_); + +/** + * @brief Returns the object's class name. + * + * @param object The object whose class name should be returned + * @return The object's class name + */ extern const char *_Nullable object_getClassName(id _Nullable object); + +/** + * @brief Returns the name of the specified protocol. + * + * @param protocol The protocol whose name should be returned + * @return The name of the specified protocol + */ extern const char *_Nonnull protocol_getName(Protocol *_Nonnull protocol); + +/** + * @brief Returns whether two protocols are equal. + * + * @param protocol1 The first protocol + * @param protocol2 The second protocol + * @return Whether the two protocols are equal + */ extern bool protocol_isEqual(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2); + +/** + * @brief Returns whether the first protocol conforms to the second protocol. + * + * @param protocol1 The first protocol + * @param protocol2 The second protocol + * @return Whether the first protocol conforms to the second protocol + */ extern bool protocol_conformsToProtocol(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2); + +/** + * @brief Copies the method list of the specified class. + * + * @param class_ The class whose method list should be copied + * @param outCount An optional pointer to an `unsigned int` that should be set + * to the number of methods returned + * @return An array of methods, terminated by `NULL`. You need to call `free()` + * on it when done. + */ extern Method _Nullable *_Nullable class_copyMethodList(Class _Nullable class_, unsigned int *_Nullable outCount); + +/** + * @brief Returns the name of the specified method. + * + * @param method The method whose name should be returned + * @return The name of the specified method + */ extern SEL _Nonnull method_getName(Method _Nonnull method); + +/** + * @brief Returns the type encoding of the specified method. + * + * @param method The method whose type encoding should be returned + * @return The type encoding of the specified method + */ extern const char *_Nullable method_getTypeEncoding(Method _Nonnull method); + +/** + * @brief Copies the instance variable list of the specified class. + * + * @param class_ The class whose instance variable list should be copied + * @param outCount An optional pointer to an `unsigned int` that should be set + * to the number of instance variables returned + * @return An array of instance variables, terminated by `NULL`. You need to + * call `free()` on it when done. + */ extern Ivar _Nullable *_Nullable class_copyIvarList(Class _Nullable class_, unsigned int *_Nullable outCount); + +/** + * @brief Returns the name of the specified instance variable. + * + * @param ivar The instance variable whose name should be returned + * @return The name of the specified instance variable + */ extern const char *_Nonnull ivar_getName(Ivar _Nonnull ivar); + +/** + * @brief Returns the type encoding of the specified instance variable. + * + * @param ivar The instance variable whose type encoding should be returned + * @return The type encoding of the specified instance variable + */ extern const char *_Nonnull ivar_getTypeEncoding(Ivar _Nonnull ivar); + +/** + * @brief Returns the offset of the specified instance variable. + * + * @param ivar The instance variable whose offset should be returned + * @return The offset of the specified instance variable + */ extern ptrdiff_t ivar_getOffset(Ivar _Nonnull ivar); + +/** + * @brief Copies the property list of the specified class. + * + * @param class_ The class whose property list should be copied + * @param outCount An optional pointer to an `unsigned int` that should be set + * to the number of properties returned + * @return An array of properties, terminated by `NULL`. You need to call + * `free()` on it when done. + */ extern objc_property_t _Nullable *_Nullable class_copyPropertyList( Class _Nullable class_, unsigned int *_Nullable outCount); + +/** + * @brief Returns the name of the specified property. + * + * @param property The property whose name should be returned + * @return The name of the specified property + */ extern const char *_Nonnull property_getName(objc_property_t _Nonnull property); + +/** + * @brief Copies the specified attribute value. + * + * @param property The property whose attribute value should be copied + * @param name The name of the attribute value to copy + * @return A copy of the attribute value. You need to call `free()` on it when + * done. + */ extern char *_Nullable property_copyAttributeValue( objc_property_t _Nonnull property, const char *_Nonnull name); + +/** + * @brief Exits the Objective-C runtime. + * + * This frees all data structures used by the runtime, after which Objective-C + * can no longer be used inside the current process. This is only useful for + * debugging. + */ extern void objc_exit(void); + +/** + * @brief Sets the handler for uncaught exceptions. + * + * @param handler The new handler for uncaught exceptions + * @return The old handler for uncaught exceptions + */ extern _Nullable objc_uncaught_exception_handler_t objc_setUncaughtExceptionHandler( objc_uncaught_exception_handler_t _Nullable handler); + +/** + * @brief Sets the forwarding handler for unimplemented methods. + * + * @param forward The forwarding handler for regular methods + * @param stretForward The forwarding handler for methods using the struct + * return ABI + */ extern void objc_setForwardHandler(IMP _Nullable forward, IMP _Nullable stretForward); + +/** + * @brief Sets the handler for mutations during enumeration. + * + * @param handler The handler for mutations during enumeration + */ extern void objc_setEnumerationMutationHandler( objc_enumeration_mutation_handler_t _Nullable handler); + +/** + * @brief Constructs an instance of the specified class in the specified array + * of bytes. + * + * @param class_ The class of which to construct an instance + * @param bytes An array of bytes of at least the length of the instance size. + * Must be properly aligned for the class. + * @return The constructed instance + */ extern id _Nullable objc_constructInstance(Class _Nullable class_, void *_Nullable bytes); + +/** + * @brief Destructs the specified object. + * + * @param object The object to destruct + * @return The array of bytes that was used to back the instance + */ extern void *_Nullable objc_destructInstance(id _Nullable object); + +/** + * @brief Creates a new autorelease pool and puts it on top of the stack of + * autorelease pools. + * + * @return A new autorelease pool, which is now on the top of the stack of + * autorelease pools + */ extern void *_Null_unspecified objc_autoreleasePoolPush(void); + +/** + * @brief Drains the specified autorelease pool and all pools on top of it and + * removes it from the stack of autorelease pools. + * + * @param pool The pool which should be drained together with all pools on top + * of it + */ extern void objc_autoreleasePoolPop(void *_Null_unspecified pool); + +/** + * @brief Adds the specified object to the topmost autorelease pool. + * + * This is only to be used to implement the `autorelease` method in a root + * class. + * + * @param object The object to add to the topmost autorelease pool + * @return The autoreleased object + */ extern id _Nullable _objc_rootAutorelease(id _Nullable object); +/** + * @brief Sets the tagged pointer secret. + * + * @param secret A secret, random value that will be used to XOR all tagged + * pointers with + */ +extern void objc_setTaggedPointerSecret(uintptr_t secret); + +/** + * @brief Registers a class for tagged pointers. + * + * @param class The class to register for tagged pointers + * @return The tagged pointer ID for the registered class + */ +extern int objc_registerTaggedPointerClass(Class _Nonnull class); + +/** + * @brief Returns whether the specified object is a tagged pointer. + * + * @param object The object to inspect + * @return Whether the specified object is a tagged pointer + */ +extern bool object_isTaggedPointer(id _Nullable object); + +/** + * @brief Returns the value of the specified tagged pointer. + * + * @param object The object whose tagged pointer value should be returned + * @return The tagged pointer value of the object + */ +extern uintptr_t object_getTaggedPointerValue(id _Nonnull object); + +/** + * @brief Creates a new tagged pointer. + * + * @param class The tag ID for the tagged pointer class to use + * @param value The value the tagged pointer should have + * @return A tagged pointer, or `nil` if it could not be created + */ +extern id _Nullable objc_createTaggedPointer(int class, uintptr_t value); + /* * Used by the compiler, but can also be called manually. * * These declarations are also required to prevent Clang's implicit * declarations which include __declspec(dllimport) on Windows. Index: src/runtime/amiga-glue.m ================================================================== --- src/runtime/amiga-glue.m +++ src/runtime/amiga-glue.m @@ -795,5 +795,54 @@ { M68K_ARG(struct objc_hashtable *, table, a0) objc_hashtable_free(table); } + +void __saveds +glue_objc_setTaggedPointerSecret PPC_PARAMS(uintptr_t secret) +{ + M68K_ARG(uintptr_t, secret, d0) + + objc_setTaggedPointerSecret(secret); +} + +int __saveds +glue_objc_registerTaggedPointerClass PPC_PARAMS(Class class) +{ + M68K_ARG(Class, class, a0) + + return objc_registerTaggedPointerClass(class); +} + +bool __saveds +glue_object_isTaggedPointer PPC_PARAMS(id object) +{ + M68K_ARG(id, object, a0) + + return object_isTaggedPointer(object); +} + +Class __saveds +glue_object_getTaggedPointerClass PPC_PARAMS(id object) +{ + M68K_ARG(id, object, a0) + + return object_getTaggedPointerClass(object); +} + +uintptr_t __saveds +glue_object_getTaggedPointerValue PPC_PARAMS(id object) +{ + M68K_ARG(id, object, a0) + + return object_getTaggedPointerValue(object); +} + +id __saveds +glue_objc_createTaggedPointer PPC_PARAMS(int class, uintptr_t value) +{ + M68K_ARG(int, class, d0) + M68K_ARG(uintptr_t, value, d1) + + return objc_createTaggedPointer(class, value); +} Index: src/runtime/amiga-library.m ================================================================== --- src/runtime/amiga-library.m +++ src/runtime/amiga-library.m @@ -146,10 +146,16 @@ extern struct objc_hashtable *glue_objc_hashtable_new(void); extern void glue_objc_hashtable_set(void); extern void *glue_objc_hashtable_get(void); extern void glue_objc_hashtable_delete(void); extern void glue_objc_hashtable_free(void); +extern void glue_objc_setTaggedPointerSecret(void); +extern int glue_objc_registerTaggedPointerClass(void); +extern bool glue_object_isTaggedPointer(void); +extern Class glue_object_getTaggedPointerClass(void); +extern uintptr_t glue_object_getTaggedPointerValue(void); +extern id glue_objc_createTaggedPointer(void); #ifdef OF_MORPHOS const ULONG __abox__ = 1; #endif struct ExecBase *SysBase; @@ -672,10 +678,16 @@ (CONST_APTR)glue_objc_hashtable_new, (CONST_APTR)glue_objc_hashtable_set, (CONST_APTR)glue_objc_hashtable_get, (CONST_APTR)glue_objc_hashtable_delete, (CONST_APTR)glue_objc_hashtable_free, + (CONST_APTR)glue_objc_setTaggedPointerSecret, + (CONST_APTR)glue_objc_registerTaggedPointerClass, + (CONST_APTR)glue_object_isTaggedPointer, + (CONST_APTR)glue_object_getTaggedPointerClass, + (CONST_APTR)glue_object_getTaggedPointerValue, + (CONST_APTR)glue_objc_createTaggedPointer, (CONST_APTR)-1, #ifdef OF_MORPHOS (CONST_APTR)FUNCARRAY_END #endif }; Index: src/runtime/amigaos3.sfd ================================================================== --- src/runtime/amigaos3.sfd +++ src/runtime/amigaos3.sfd @@ -87,6 +87,13 @@ struct objc_hashtable *_Nonnull glue_objc_hashtable_new(objc_hashtable_hash_func hash, objc_hashtable_equal_func equal, uint32_t size)(a0,a1,d0) void glue_objc_hashtable_set(struct objc_hashtable *_Nonnull table, const void *_Nonnull key, const void *_Nonnull object)(a0,a1,a2) void *_Nullable glue_objc_hashtable_get(struct objc_hashtable *_Nonnull table, const void *_Nonnull key)(a0,a1) void glue_objc_hashtable_delete(struct objc_hashtable *_Nonnull table, const void *_Nonnull key)(a0,a1) void glue_objc_hashtable_free(struct objc_hashtable *_Nonnull table)(a0) +* Public functions again +void glue_objc_setTaggedPointerSecret(uintptr_t secret)(d0) +int glue_objc_registerTaggedPointerClass(Class _Nonnull class_)(a0) +bool glue_object_isTaggedPointer(id _Nullable object)(a0) +Class _Nullable glue_object_getTaggedPointerClass(id _Nonnull object)(a0) +uintptr_t glue_object_getTaggedPointerValue(id _Nonnull object)(a0) +id _Nullable glue_objc_createTaggedPointer(int class_, uintptr_t value)(d0,d1) ==end Index: src/runtime/autorelease.m ================================================================== --- src/runtime/autorelease.m +++ src/runtime/autorelease.m @@ -18,16 +18,27 @@ #include "config.h" #include #include -#import "ObjFWRT.h" -#import "private.h" +#ifdef OF_OBJFW_RUNTIME +# import "ObjFWRT.h" +# import "private.h" +#else +# import +#endif +#import "macros.h" #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) # import "tlskey.h" #endif + +#ifndef OF_OBJFW_RUNTIME +@interface DummyObject +- (void)release; +@end +#endif #if defined(OF_HAVE_COMPILER_TLS) static thread_local id *objects = NULL; static thread_local uintptr_t count = 0; static thread_local uintptr_t size = 0; Index: src/runtime/class.m ================================================================== --- src/runtime/class.m +++ src/runtime/class.m @@ -468,11 +468,11 @@ { struct objc_class *class, *metaclass; Class iter, rootclass = Nil; if (extraBytes > LONG_MAX) - OBJC_ERROR("extra_bytes out of range!") + OBJC_ERROR("extraBytes out of range!") if ((class = calloc(1, sizeof(*class))) == NULL || (metaclass = calloc(1, sizeof(*class))) == NULL) OBJC_ERROR("Not enough memory to allocate class pair for class " "%s!", name) @@ -844,10 +844,13 @@ struct objc_object *object; if (object_ == nil) return Nil; + if (object_isTaggedPointer(object_)) + return object_getTaggedPointerClass(object_); + object = (struct objc_object *)object_; return object->isa; } Index: src/runtime/instance.m ================================================================== --- src/runtime/instance.m +++ src/runtime/instance.m @@ -15,12 +15,18 @@ * file. */ #include "config.h" -#import "ObjFWRT.h" -#import "private.h" +#include + +#ifdef OF_OBJFW_RUNTIME +# import "ObjFWRT.h" +# import "private.h" +#else +# import +#endif static SEL constructSelector = NULL; static SEL destructSelector = NULL; static bool Index: src/runtime/linklib/linklib.m ================================================================== --- src/runtime/linklib/linklib.m +++ src/runtime/linklib/linklib.m @@ -721,5 +721,41 @@ void objc_hashtable_free(struct objc_hashtable *table) { glue_objc_hashtable_free(table); } + +void +objc_setTaggedPointerSecret(uintptr_t secret) +{ + glue_objc_setTaggedPointerSecret(secret); +} + +int +objc_registerTaggedPointerClass(Class class) +{ + return glue_objc_registerTaggedPointerClass(class); +} + +bool +object_isTaggedPointer(id object) +{ + return glue_object_isTaggedPointer(object); +} + +Class +object_getTaggedPointerClass(id object) +{ + return glue_object_getTaggedPointerClass(object); +} + +uintptr_t +object_getTaggedPointerValue(id object) +{ + return glue_object_getTaggedPointerValue(object); +} + +id +objc_createTaggedPointer(int class, uintptr_t value) +{ + return objc_createTaggedPointer(class, value); +} Index: src/runtime/lookup-asm/lookup-asm-arm-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-arm-elf.S +++ src/runtime/lookup-asm/lookup-asm-arm-elf.S @@ -28,10 +28,13 @@ .macro generate_lookup name not_found \name: cmp r0, #0 beq ret_nil + tst r0, #1 + bne .Ltagged_pointer_\name + ldr r2, [r0, #0] ldr r2, [r2, #32] .Lmain_\name: #ifndef OF_BIG_ENDIAN @@ -57,12 +60,35 @@ cmp r2, #0 beq \not_found(PLT) mov r0, r2 bx lr + +.Ltagged_pointer_\name: + ldr r2, .Lgot$indirect_.Ltagged_pointer_\name + add r2, pc, r2 + + ldr r3, .Lgot$indirect_.Ltagged_pointer_\name+4 + ldr r3, [r2, r3] + ldr r3, [r3] + eor r0, r0, r3 + and r0, r0, #0xE + lsl r0, r0, #1 + + ldr r3, .Lgot$indirect_.Ltagged_pointer_\name+8 + ldr r3, [r2, r3] + ldr r2, [r3, r0] + ldr r2, [r2, #32] + + b .Lmain_\name .type \name, %function .size \name, .-\name + +.Lgot$indirect_.Ltagged_pointer_\name: + .long _GLOBAL_OFFSET_TABLE_-(.Ltagged_pointer_\name+12) + .long objc_tagged_pointer_secret(GOT) + .long objc_tagged_pointer_classes(GOT) .endm .macro generate_lookup_super name lookup \name: mov r2, r0 Index: src/runtime/lookup-asm/lookup-asm-arm64-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-arm64-elf.S +++ src/runtime/lookup-asm/lookup-asm-arm64-elf.S @@ -25,41 +25,56 @@ .globl objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - cmp x0, #0 - beq ret_nil + cbz x0, ret_nil + + tst x0, #1 + b.ne .Ltagged_pointer_\name - ldr x2, [x0, #0] + ldr x2, [x0] ldr x2, [x2, #64] .Lmain_\name: #ifdef OF_SELUID24 ldrb w3, [x1, #2] ldr x2, [x2, x3, lsl #3] #endif ldrb w3, [x1, #1] ldr x2, [x2, x3, lsl #3] - ldrb w3, [x1, #0] + ldrb w3, [x1] ldr x2, [x2, x3, lsl #3] - cmp x2, #0 - beq \not_found + cbz x2, \not_found mov x0, x2 ret + +.Ltagged_pointer_\name: + adrp x2, :got:objc_tagged_pointer_secret + ldr x2, [x2, #:got_lo12:objc_tagged_pointer_secret] + ldr x2, [x2] + eor x0, x0, x2 + and x0, x0, #0xE + lsl x0, x0, #2 + + adrp x2, :got:objc_tagged_pointer_classes + ldr x2, [x2, #:got_lo12:objc_tagged_pointer_classes] + ldr x2, [x2, x0] + ldr x2, [x2, #64] + + b .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup \name: mov x2, x0 - ldr x0, [x0, #0] - cmp x0, #0 - beq ret_nil + ldr x0, [x0] + cbz x0, ret_nil ldr x2, [x2, #8] ldr x2, [x2, #64] b .Lmain_\lookup Index: src/runtime/lookup-asm/lookup-asm-mips-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-mips-elf.S +++ src/runtime/lookup-asm/lookup-asm-mips-elf.S @@ -27,10 +27,13 @@ .section .text .macro generate_lookup name not_found \name: beqz $a0, 0f + andi $t0, $a0, 1 + bnez $t0, .Ltagged_pointer_\name + lw $t0, 0($a0) lw $t0, 32($t0) .Lmain_\name: #ifdef OF_BIG_ENDIAN @@ -87,10 +90,38 @@ addiu $gp, $gp, 1b-\name lw $t9, %call16(\not_found)($gp) jr $t9 #endif + +.Ltagged_pointer_\name: +#ifdef OF_PIC +0: + lui $gp, %hi(_gp_disp) + addiu $gp, $gp, %lo(_gp_disp) + addu $gp, $gp, $t9 + addiu $gp, $gp, 0b-\name + + lw $t0, %got(objc_tagged_pointer_secret)($gp) +#else + la $t0, objc_tagged_pointer_secret +#endif + lw $t0, 0($t0) + xor $t0, $a0, $t0 + and $t0, $t0, 0xE + sll $t0, $t0, 1 + +#ifdef OF_PIC + lw $t1, %got(objc_tagged_pointer_classes)($gp) +#else + la $t1, objc_tagged_pointer_classes +#endif + addu $t0, $t1, $t0 + ld $t0, ($t0) + ld $t0, 32($t0) + + b .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup Index: src/runtime/lookup-asm/lookup-asm-mips64-n64-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-mips64-n64-elf.S +++ src/runtime/lookup-asm/lookup-asm-mips64-n64-elf.S @@ -27,11 +27,14 @@ .section .text .macro generate_lookup name not_found \name: beqz $a0, 0f - ld $t0, 0($a0) + andi $t0, $a0, 1 + bnez $t0, .Ltagged_pointer_\name + + ld $t0, ($a0) ld $t0, 64($t0) .Lmain_\name: #ifdef OF_BIG_ENDIAN # ifdef OF_SELUID24 @@ -42,11 +45,11 @@ #else # ifdef OF_SELUID24 lbu $t1, 2($a1) # endif lbu $t2, 1($a1) - lbu $t3, 0($a1) + lbu $t3, ($a1) #endif #ifdef OF_SELUID24 sll $t1, $t1, 3 #endif @@ -53,43 +56,61 @@ sll $t2, $t2, 3 sll $t3, $t3, 3 #ifdef OF_SELUID24 daddu $t0, $t0, $t1 - ld $t0, 0($t0) + ld $t0, ($t0) #endif daddu $t0, $t0, $t2 - ld $t0, 0($t0) + ld $t0, ($t0) daddu $t0, $t0, $t3 - ld $t0, 0($t0) + ld $t0, ($t0) beqz $t0, 1f move $v0, $t0 jr $ra 0: lui $v0, %hi(%neg(%gp_rel(\name))) - daddu $v0, $v0, $t9 daddiu $v0, $v0, %lo(%neg(%gp_rel(\name))) + daddu $v0, $v0, $t9 ld $v0, %got_disp(nil_method)($v0) jr $ra 1: lui $t0, %hi(%neg(%gp_rel(\name))) - daddu $t0, $t0, $t9 daddiu $t0, $t0, %lo(%neg(%gp_rel(\name))) + daddu $t0, $t0, $t9 ld $t9, %got_disp(\not_found)($t0) jr $t9 + +.Ltagged_pointer_\name: + lui $t0, %hi(%neg(%gp_rel(\name))) + daddiu $t0, $t0, %lo(%neg(%gp_rel(\name))) + daddu $t0, $t0, $t9 + + ld $t1, %got_disp(objc_tagged_pointer_secret)($t0) + ld $t1, 0($t1) + xor $t1, $a0, $t1 + and $t1, $t1, 0xE + dsll $t1, $t1, 2 + + ld $t0, %got_disp(objc_tagged_pointer_classes)($t0) + daddu $t0, $t0, $t1 + ld $t0, ($t0) + ld $t0, 64($t0) + + b .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup \name: move $t0, $a0 - ld $a0, 0($a0) + ld $a0, ($a0) beqz $a0, 0f ld $t0, 8($t0) ld $t0, 64($t0) @@ -96,12 +117,12 @@ daddiu $t9, $t9, \lookup-\name b .Lmain_\lookup 0: lui $v0, %hi(%neg(%gp_rel(\name))) - daddu $v0, $v0, $t9 daddiu $v0, $v0, %lo(%neg(%gp_rel(\name))) + daddu $v0, $v0, $t9 ld $v0, %got_disp(nil_method)($v0) jr $ra .type \name, %function .size \name, .-\name .endm Index: src/runtime/lookup-asm/lookup-asm-powerpc-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-powerpc-elf.S +++ src/runtime/lookup-asm/lookup-asm-powerpc-elf.S @@ -28,10 +28,13 @@ .macro generate_lookup name not_found \name: cmpwi %r3, 0 beq- ret_nil + andi. %r0, %r3, 1 + bne- .Ltagged_pointer_\name + lwz %r5, 0(%r3) lwz %r5, 32(%r5) .Lmain_\name: lwz %r8, 0(%r4) @@ -52,11 +55,50 @@ mr %r3, %r5 blr 0: - b \not_found@plt + stwu %r1, -16(%r1) + mflr %r0 + stw %r0, 20(%r1) + stw %r30, 8(%r1) + + bl 0f +0: + mflr %r30 + addis %r30, %r30, .Lbiased_got2-0b@ha + addi %r30, %r30, .Lbiased_got2-0b@l + + lwz %r0, .Lgot_\not_found-.Lbiased_got2(%r30) + mtctr %r0 + + lwz %r30, 8(%r1) + lwz %r0, 20(%r1) + addi %r1, %r1, 16 + mtlr %r0 + + bctr + +.Ltagged_pointer_\name: + mflr %r7 + bl 0f +0: + mflr %r6 + mtlr %r7 + addis %r6, %r6, .Lbiased_got2-0b@ha + addi %r6, %r6, .Lbiased_got2-0b@l + + lwz %r5, .Lgot_objc_tagged_pointer_secret-.Lbiased_got2(%r6) + lwz %r5, 0(%r5) + xor %r5, %r3, %r5 + rlwinm %r5, %r5, 1, 0x1C + + lwz %r6, .Lgot_objc_tagged_pointer_classes-.Lbiased_got2(%r6) + lwzx %r5, %r6, %r5 + lwz %r5, 32(%r5) + + b .Lmain_\name .type \name, @function .size \name, .-\name .endm .macro generate_lookup_super name lookup @@ -93,8 +135,19 @@ get_pc: mflr %r3 blr +.section .got2, "aw" +.Lbiased_got2 = .+0x8000 +.Lgot_objc_method_not_found: + .long objc_method_not_found +.Lgot_objc_method_not_found_stret: + .long objc_method_not_found_stret +.Lgot_objc_tagged_pointer_secret: + .long objc_tagged_pointer_secret +.Lgot_objc_tagged_pointer_classes: + .long objc_tagged_pointer_classes + #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif DELETED src/runtime/lookup-asm/lookup-asm-powerpc-macho.S Index: src/runtime/lookup-asm/lookup-asm-powerpc-macho.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-powerpc-macho.S +++ src/runtime/lookup-asm/lookup-asm-powerpc-macho.S @@ -1,90 +0,0 @@ -/* - * 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" - -.globl _objc_msg_lookup -.globl _objc_msg_lookup_stret -.globl _objc_msg_lookup_super -.globl _objc_msg_lookup_super_stret - -.section __TEXT, __text, regular, pure_instructions -.macro generate_lookup -$0: - cmpwi r3, 0 - beq- ret_nil - - lwz r5, 0(r3) - lwz r5, 32(r5) - -Lmain_$0: - lwz r8, 0(r4) -#ifdef OF_SELUID24 - rlwinm r6, r8, 18, 0x3FC -#endif - rlwinm r7, r8, 26, 0x3FC - rlwinm r8, r8, 2, 0x3FC - -#ifdef OF_SELUID24 - lwzx r5, r5, r6 -#endif - lwzx r5, r5, r7 - lwzx r5, r5, r8 - - cmpwi r5, 0 - beq- 0f - - mr r3, r5 - blr - -0: - b $1 -.endmacro - -.macro generate_lookup_super -$0: - mr r5, r3 - lwz r3, 0(r3) - cmpwi r3, 0 - beq- ret_nil - - lwz r5, 4(r5) - lwz r5, 32(r5) - - b Lmain_$1 -.endmacro - -generate_lookup _objc_msg_lookup, _objc_method_not_found -generate_lookup _objc_msg_lookup_stret, _objc_method_not_found_stret -generate_lookup_super _objc_msg_lookup_super, _objc_msg_lookup -generate_lookup_super _objc_msg_lookup_super_stret, _objc_msg_lookup_stret - -ret_nil: - mflr r0 - bl get_pc - mtlr r0 -0: - addi r3, r3, lo16(nil_method-0b) - blr - -nil_method: - li r3, 0 - blr - -get_pc: - mflr r3 - blr Index: src/runtime/lookup-asm/lookup-asm-sparc-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-sparc-elf.S +++ src/runtime/lookup-asm/lookup-asm-sparc-elf.S @@ -25,12 +25,14 @@ .globl objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - cmp %o0, 0 - be ret_nil + tst %o0 + bz ret_nil + btst 1, %o0 + bnz .Ltagged_pointer_\name nop ld [%o0], %o2 ld [%o2 + 32], %o2 @@ -62,10 +64,41 @@ 0: mov %o7, %g1 call \not_found mov %g1, %o7 + +.Ltagged_pointer_\name: +#ifdef OF_PIC + mov %o7, %g1 + sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o3 + call 0f + or %o3, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o3 +0: + add %o7, %o3, %o3 + mov %g1, %o7 +#endif + + sethi %hi(objc_tagged_pointer_secret), %o2 + or %o2, %lo(objc_tagged_pointer_secret), %o2 +#ifdef OF_PIC + ld [%o3 + %o2], %o2 +#endif + ld [%o2], %o2 + xor %o0, %o2, %o0 + and %o0, 0xE, %o0 + sll %o0, 1, %o0 + + sethi %hi(objc_tagged_pointer_classes), %o2 + or %o2, %lo(objc_tagged_pointer_classes), %o2 +#ifdef OF_PIC + ld [%o3 + %o2], %o2 +#endif + + ld [%o2 + %o0], %o2 + ba .Lmain_\name + ld [%o2 + 32], %o2 .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup Index: src/runtime/lookup-asm/lookup-asm-sparc64-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-sparc64-elf.S +++ src/runtime/lookup-asm/lookup-asm-sparc64-elf.S @@ -26,10 +26,12 @@ .section .text .macro generate_lookup name not_found \name: brz,pn %o0, ret_nil + and %o0, 1, %o2 + brnz,pn %o2, .Ltagged_pointer_\name nop ldx [%o0], %o2 ldx [%o2 + 64], %o2 @@ -50,21 +52,51 @@ ldx [%o2 + %o3], %o2 #endif ldx [%o2 + %o4], %o2 ldx [%o2 + %o5], %o2 - cmp %o2, 0 - be,pn %xcc, 0f + brz,pn %o2, 0f nop retl mov %o2, %o0 0: mov %o7, %g1 call \not_found mov %g1, %o7 + +.Ltagged_pointer_\name: +#ifdef OF_PIC + mov %o7, %g1 + sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o3 + call 0f + or %o3, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o3 +0: + add %o7, %o3, %o3 + mov %g1, %o7 +#endif + + sethi %hi(objc_tagged_pointer_secret), %o2 + or %o2, %lo(objc_tagged_pointer_secret), %o2 +#ifdef OF_PIC + ldx [%o3 + %o2], %o2 +#endif + ldx [%o2], %o2 + xor %o0, %o2, %o0 + and %o0, 0xE, %o0 + sll %o0, 2, %o0 + + sethi %hi(objc_tagged_pointer_classes), %o2 + or %o2, %lo(objc_tagged_pointer_classes), %o2 +#ifdef OF_PIC + ldx [%o3 + %o2], %o2 +#endif + + ldx [%o2 + %o0], %o2 + ba .Lmain_\name + ldx [%o2 + 64], %o2 .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup @@ -90,11 +122,11 @@ #ifdef OF_PIC mov %o7, %g1 sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o1 call 0f - add %o1, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o1 + or %o1, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o1 0: add %o7, %o1, %o1 sethi %hi(nil_method), %o0 or %o0, %lo(nil_method), %o0 Index: src/runtime/lookup-asm/lookup-asm-x86-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86-elf.S +++ src/runtime/lookup-asm/lookup-asm-x86-elf.S @@ -31,10 +31,13 @@ \name: mov edx, [esp+4] test edx, edx jz short ret_nil + bt edx, 0 + jc short .Ltagged_pointer_\name + mov edx, [edx] mov edx, [edx+32] .Lmain_\name: mov eax, [esp+8] @@ -56,10 +59,25 @@ 0: call get_eip add eax, offset _GLOBAL_OFFSET_TABLE_ lea eax, [eax+\not_found@GOTOFF] jmp eax + +.Ltagged_pointer_\name: + call get_eip + add eax, offset _GLOBAL_OFFSET_TABLE_ + + lea ecx, [eax+objc_tagged_pointer_secret@GOTOFF] + xor edx, [ecx] + and dl, 0xE + movzx edx, dl + + lea eax, [eax+objc_tagged_pointer_classes@GOTOFF] + mov edx, [eax+edx*2] + mov edx, [edx+32] + + jmp short .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup Index: src/runtime/lookup-asm/lookup-asm-x86-win32.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86-win32.S +++ src/runtime/lookup-asm/lookup-asm-x86-win32.S @@ -29,10 +29,13 @@ \name: mov edx, [esp+4] test edx, edx jz short ret_nil + bt edx, 0 + jc short .Ltagged_pointer_\name + mov edx, [edx] mov edx, [edx+32] .Lmain_\name: mov eax, [esp+8] @@ -45,16 +48,23 @@ mov edx, [edx+ecx*4] movzx ecx, byte ptr [eax] mov eax, [edx+ecx*4] test eax, eax - jz short 0f + jz \not_found ret -0: - jmp \not_found +.Ltagged_pointer_\name: + xor edx, _objc_tagged_pointer_secret + and dl, 0xE + movzx edx, dl + + mov edx, [_objc_tagged_pointer_classes+edx*2] + mov edx, [edx+32] + + jmp short .Lmain_\name .endm .macro generate_lookup_super name lookup \name: mov edx, [esp+4] Index: src/runtime/lookup-asm/lookup-asm-x86_64-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86_64-elf.S +++ src/runtime/lookup-asm/lookup-asm-x86_64-elf.S @@ -30,10 +30,13 @@ .macro generate_lookup name not_found \name: test rdi, rdi jz short ret_nil + bt edi, 0 + jc short .Ltagged_pointer_\name + mov r8, [rdi] mov r8, [r8+64] .Lmain_\name: mov rax, [rsi] @@ -49,10 +52,22 @@ test rax, rax jz short \not_found@PLT ret + +.Ltagged_pointer_\name: + mov rax, [rip+objc_tagged_pointer_secret@GOTPCREL] + xor rdi, [rax] + and dil, 0xE + movzx r8, dil + + mov rax, [rip+objc_tagged_pointer_classes@GOTPCREL] + mov r8, [rax+r8*4] + mov r8, [r8+64] + + jmp short .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup Index: src/runtime/lookup-asm/lookup-asm-x86_64-macho.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86_64-macho.S +++ src/runtime/lookup-asm/lookup-asm-x86_64-macho.S @@ -28,10 +28,13 @@ .macro generate_lookup $0: test rdi, rdi jz ret_nil + bt edi, 0 + jc Ltagged_pointer_$0 + mov r8, [rdi] mov r8, [r8+64] Lmain_$0: mov rax, [rsi] @@ -47,10 +50,22 @@ test rax, rax jz $1 ret + +Ltagged_pointer_$0: + mov rax, [rip+_objc_tagged_pointer_secret@GOTPCREL] + xor rdi, [rax] + and dil, 0xE + movzx r8, dil + + mov rax, [rip+_objc_tagged_pointer_classes@GOTPCREL] + mov r8, [rax+r8*4] + mov r8, [r8+64] + + jmp Lmain_$0 .endmacro .macro generate_lookup_super $0: mov r8, rdi Index: src/runtime/lookup-asm/lookup-asm-x86_64-win64.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86_64-win64.S +++ src/runtime/lookup-asm/lookup-asm-x86_64-win64.S @@ -25,13 +25,16 @@ .globl objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - test %rcx, %rcx + test rcx, rcx jz short ret_nil + bt ecx, 0 + jc short .Ltagged_pointer_\name + mov r8, [rcx] mov r8, [r8+56] .Lmain_\name: mov r10, rcx @@ -55,10 +58,20 @@ 0: mov rcx, r10 mov rdx, r11 jmp \not_found + +.Ltagged_pointer_\name: + xor rcx, objc_tagged_pointer_secret + and cl, 0xE + movzx r8, cl + + mov r8, [objc_tagged_pointer_classes+r8*4] + mov r8, [r8+56] + + jmp short .Lmain_\name .endm .macro generate_lookup_super name lookup \name: mov r8, rcx Index: src/runtime/lookup-asm/lookup-asm.S ================================================================== --- src/runtime/lookup-asm/lookup-asm.S +++ src/runtime/lookup-asm/lookup-asm.S @@ -40,15 +40,13 @@ # include "lookup-asm-sparc-elf.S" # endif #elif defined(OF_MACH_O) # if defined(OF_X86_64) # include "lookup-asm-x86_64-macho.S" -# elif defined(OF_POWERPC) -# include "lookup-asm-powerpc-macho.S" # endif #elif defined(OF_WINDOWS) # if defined(OF_X86_64) # include "lookup-asm-x86_64-win64.S" # elif defined(OF_X86) # include "lookup-asm-x86-win32.S" # endif #endif Index: src/runtime/morphos-clib.h ================================================================== --- src/runtime/morphos-clib.h +++ src/runtime/morphos-clib.h @@ -77,10 +77,17 @@ void *glue_objc_destructInstance(id); void *glue_objc_autoreleasePoolPush(void); void glue_objc_autoreleasePoolPop(void *); id glue__objc_rootAutorelease(id); /* The following functions are private! Don't use! */ -struct objc_hashtable *glue_objc_hashtable_new(objc_hashtable_hash_func hash, objc_hashtable_equal_func equal, uint32_t size); -void glue_objc_hashtable_set(struct objc_hashtable *table, const void *key, const void *object); -void *glue_objc_hashtable_get(struct objc_hashtable *table, const void *key); -void glue_objc_hashtable_delete(struct objc_hashtable *table, const void *key); -void glue_objc_hashtable_free(struct objc_hashtable *table); +struct objc_hashtable *glue_objc_hashtable_new(objc_hashtable_hash_func, objc_hashtable_equal_func, uint32_t); +void glue_objc_hashtable_set(struct objc_hashtable *, const void *, const void *); +void *glue_objc_hashtable_get(struct objc_hashtable *, const void *); +void glue_objc_hashtable_delete(struct objc_hashtable *, const void *); +void glue_objc_hashtable_free(struct objc_hashtable *); +/* Public functions again */ +void glue_objc_setTaggedPointerSecret(uintptr_t); +int glue_objc_registerTaggedPointerClass(Class); +bool glue_object_isTaggedPointer(id); +Class _Nullable glue_object_getTaggedPointerClass(id); +uintptr_t glue_object_getTaggedPointerValue(id); +id glue_objc_createTaggedPointer(int, uintptr_t); Index: src/runtime/morphos.fd ================================================================== --- src/runtime/morphos.fd +++ src/runtime/morphos.fd @@ -85,6 +85,13 @@ glue_objc_hashtable_new(hash,equal,size)(sysv,r12base) glue_objc_hashtable_set(table,key,object)(sysv,r12base) glue_objc_hashtable_get(table,key)(sysv,r12base) glue_objc_hashtable_delete(table,key)(sysv,r12base) glue_objc_hashtable_free(table)(sysv,r12base) +* Public functions again +glue_objc_setTaggedPointerSecret(secret)(sysv,r12base) +glue_objc_registerTaggedPointerClass(class_)(sysv,r12base) +glue_object_isTaggedPointer(object)(sysv,r12base) +glue_object_getTaggedPointerClass(object)(sysv,r12base) +glue_object_getTaggedPointerValue(object)(sysv,r12base) +glue_objc_createTaggedPointer(class_,value)(sysv,r12base) ##end Index: src/runtime/private.h ================================================================== --- src/runtime/private.h +++ src/runtime/private.h @@ -255,10 +255,11 @@ extern void objc_dtable_free(struct objc_dtable *_Nonnull); extern void objc_dtable_cleanup(void); extern void objc_init_static_instances(struct objc_symtab *_Nonnull); extern void objc_forget_pending_static_instances(void); extern void objc_zero_weak_references(id _Nonnull); +extern Class _Nullable object_getTaggedPointerClass(id _Nonnull); #ifdef OF_HAVE_THREADS extern void objc_global_mutex_lock(void); extern void objc_global_mutex_unlock(void); extern void objc_global_mutex_free(void); #else @@ -290,11 +291,11 @@ defined(OF_MIPS64_N64) || defined(OF_MIPS) || \ defined(OF_SPARC64) || defined(OF_SPARC) # define OF_ASM_LOOKUP # endif #elif defined(OF_MACH_O) -# if defined(OF_X86_64) || defined(OF_POWERPC) +# if defined(OF_X86_64) # define OF_ASM_LOOKUP # endif #elif defined(OF_WINDOWS) # if defined(OF_X86_64) || defined(OF_X86) # define OF_ASM_LOOKUP ADDED src/runtime/tagged-pointer.m Index: src/runtime/tagged-pointer.m ================================================================== --- src/runtime/tagged-pointer.m +++ src/runtime/tagged-pointer.m @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#import "ObjFWRT.h" + +#import "private.h" + +#define TAGGED_POINTER_BITS 4 +#define NUM_TAGGED_POINTER_CLASSES (1 << (TAGGED_POINTER_BITS - 1)) + +Class objc_tagged_pointer_classes[NUM_TAGGED_POINTER_CLASSES]; +static int taggedPointerClassesCount; +uintptr_t objc_tagged_pointer_secret; + +void +objc_setTaggedPointerSecret(uintptr_t secret) +{ + objc_tagged_pointer_secret = secret & ~(uintptr_t)1; +} + +int +objc_registerTaggedPointerClass(Class class) +{ + int i; + + objc_global_mutex_lock(); + + if (taggedPointerClassesCount == NUM_TAGGED_POINTER_CLASSES) { + objc_global_mutex_unlock(); + return -1; + } + + i = taggedPointerClassesCount++; + objc_tagged_pointer_classes[i] = class; + + objc_global_mutex_unlock(); + + return i; +} + +bool +object_isTaggedPointer(id object) +{ + uintptr_t pointer = (uintptr_t)object; + + return pointer & 1; +} + +Class +object_getTaggedPointerClass(id object) +{ + uintptr_t pointer = (uintptr_t)object ^ objc_tagged_pointer_secret; + + pointer &= (1 << TAGGED_POINTER_BITS) - 1; + pointer >>= 1; + + if (pointer >= NUM_TAGGED_POINTER_CLASSES) + return Nil; + + return objc_tagged_pointer_classes[pointer]; +} + +uintptr_t +object_getTaggedPointerValue(id object) +{ + uintptr_t pointer = (uintptr_t)object ^ objc_tagged_pointer_secret; + + pointer >>= TAGGED_POINTER_BITS; + + return pointer; +} + +id +objc_createTaggedPointer(int class, uintptr_t value) +{ + uintptr_t pointer; + + if (class < 0 || class >= NUM_TAGGED_POINTER_CLASSES) + return nil; + + if (value > (UINTPTR_MAX >> TAGGED_POINTER_BITS)) + return nil; + + pointer = (class << 1) | 1; + pointer |= (value << TAGGED_POINTER_BITS); + + return (id)(pointer ^ objc_tagged_pointer_secret); +} Index: src/scrypt.h ================================================================== --- src/scrypt.h +++ src/scrypt.h @@ -24,41 +24,41 @@ #import "macros.h" OF_ASSUME_NONNULL_BEGIN -/*! @file */ +/** @file */ @class OFHMAC; -/*! +/** * @brief The parameters for @ref of_scrypt. */ typedef struct of_scrypt_parameters_t { - /*! @brief The block size to use. */ + /** @brief The block size to use. */ size_t blockSize; - /*! @brief The CPU/memory cost factor to use. */ + /** @brief The CPU/memory cost factor to use. */ size_t costFactor; - /*! @brief The parallelization to use. */ + /** @brief The parallelization to use. */ size_t parallelization; - /*! @brief The salt to derive a key with. */ + /** @brief The salt to derive a key with. */ const unsigned char *salt; - /*! @brief The length of the salt. */ + /** @brief The length of the salt. */ size_t saltLength; - /*! @brief The password to derive a key from. */ + /** @brief The password to derive a key from. */ const char *password; - /*! @brief The length of the password. */ + /** @brief The length of the password. */ size_t passwordLength; - /*! @brief The buffer to write the key to. */ + /** @brief The buffer to write the key to. */ unsigned char *key; - /*! + /** * @brief The desired length for the derived key. * * @ref key needs to have enough storage. */ size_t keyLength; - /*! @brief Whether data may be stored in swappable memory. */ + /** @brief Whether data may be stored in swappable memory. */ bool allowsSwappableMemory; } of_scrypt_parameters_t; #ifdef __cplusplus extern "C" { @@ -67,11 +67,11 @@ extern void of_scrypt_block_mix(uint32_t *output, const uint32_t *input, size_t blockSize); extern void of_scrypt_romix(uint32_t *buffer, size_t blockSize, size_t costFactor, uint32_t *tmp); -/*! +/** * @brief Derives a key from a password and a salt using scrypt. * * @param param The parameters to use */ extern void of_scrypt(of_scrypt_parameters_t param); Index: src/socket.h ================================================================== --- src/socket.h +++ src/socket.h @@ -49,11 +49,11 @@ # ifdef OF_HAVE_IPX # include # endif #endif -/*! @file */ +/** @file */ #ifdef OF_WII # include #endif @@ -86,11 +86,11 @@ #ifdef OF_MORPHOS_IXEMUL typedef int socklen_t; #endif -/*! +/** * @brief A socket address family. */ typedef enum { /** An unknown address family. */ OF_SOCKET_ADDRESS_FAMILY_UNKNOWN, @@ -132,11 +132,11 @@ # define sipx_network sa_netnum # define sipx_node sa_nodenum # define sipx_port sa_socket #endif -/*! +/** * @struct of_socket_address_t socket.h ObjFW/socket.h * * @brief A struct which represents a host / port pair for a socket. */ struct OF_BOXABLE of_socket_address_t { @@ -159,41 +159,41 @@ typedef struct of_socket_address_t of_socket_address_t; #ifdef __cplusplus extern "C" { #endif -/*! +/** * @brief Parses the specified IP and port into an of_socket_address_t. * * @param IP The IP to parse * @param port The port to use * @return The parsed IP and port as an of_socket_address_t */ extern of_socket_address_t of_socket_address_parse_ip( OFString *IP, uint16_t port); -/*! +/** * @brief Parses the specified IPv4 and port into an of_socket_address_t. * * @param IP The IPv4 to parse * @param port The port to use * @return The parsed IPv4 and port as an of_socket_address_t */ extern of_socket_address_t of_socket_address_parse_ipv4( OFString *IP, uint16_t port); -/*! +/** * @brief Parses the specified IPv6 and port into an of_socket_address_t. * * @param IP The IPv6 to parse * @param port The port to use * @return The parsed IPv6 and port as an of_socket_address_t */ extern of_socket_address_t of_socket_address_parse_ipv6( OFString *IP, uint16_t port); -/*! +/** * @brief Creates an IPX address for the specified network, node and port. * * @param node The node in the IPX network * @param network The IPX network * @param port The IPX port (sometimes called socket number) on the node @@ -200,11 +200,11 @@ */ extern of_socket_address_t of_socket_address_ipx( const unsigned char node[_Nonnull IPX_NODE_LEN], uint32_t network, uint16_t port); -/*! +/** * @brief Compares two of_socket_address_t for equality. * * @param address1 The address to compare with the second address * @param address2 The second address * @return Whether the two addresses are equal @@ -211,20 +211,20 @@ */ extern bool of_socket_address_equal( const of_socket_address_t *_Nonnull address1, const of_socket_address_t *_Nonnull address2); -/*! +/** * @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( const of_socket_address_t *_Nonnull address); -/*! +/** * @brief Converts the specified of_socket_address_t to an IP string and port. * * @param address The address to convert to a string * @param port A pointer to an uint16_t which should be set to the port of the * address or NULL if the port is not needed @@ -231,59 +231,59 @@ * @return The address as an IP string */ extern OFString *_Nonnull of_socket_address_ip_string( const of_socket_address_t *_Nonnull address, uint16_t *_Nullable port); -/*! +/** * @brief Sets the port of the specified of_socket_address_t, independent of * the address family used. * * @param address The address on which to set the port * @param port The port to set on the address */ extern void of_socket_address_set_port(of_socket_address_t *_Nonnull address, uint16_t port); -/*! +/** * @brief Returns the port of the specified of_socket_address_t, independent of * the address family used. * * @param address The address on which to get the port * @return The port of the address */ extern uint16_t of_socket_address_get_port( const of_socket_address_t *_Nonnull address); -/*! +/** * @brief Sets the IPX network of the specified of_socket_address_t. * * @param address The address on which to set the IPX network * @param network The IPX network to set on the address */ extern void of_socket_address_set_ipx_network( of_socket_address_t *_Nonnull address, uint32_t network); -/*! +/** * @brief Returns the IPX network of the specified of_socket_address_t. * * @param address The address on which to get the IPX network * @return The IPX network of the address */ extern uint32_t of_socket_address_get_ipx_network( const of_socket_address_t *_Nonnull address); -/*! +/** * @brief Sets the IPX node of the specified of_socket_address_t. * * @param address The address on which to set the IPX node * @param node The IPX node to set on the address */ extern void of_socket_address_set_ipx_node( of_socket_address_t *_Nonnull address, const unsigned char node[_Nonnull IPX_NODE_LEN]); -/*! +/** * @brief Gets the IPX node of the specified of_socket_address_t. * * @param address The address on which to get the IPX node * @param node A byte array to store the IPX node of the address */ Index: src/socket.m ================================================================== --- src/socket.m +++ src/socket.m @@ -42,11 +42,11 @@ # import "mutex.h" # else # import "tlskey.h" # endif #endif -#include "once.h" +#import "once.h" #ifdef OF_AMIGAOS # include #endif @@ -374,25 +374,25 @@ @throw [OFInvalidFormatException exception]; addr = 0; for (OFString *component in components) { - intmax_t number; + unsigned long long number; if (component.length == 0) @throw [OFInvalidFormatException exception]; if ([component indexOfCharacterFromSet: whitespaceCharacterSet] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; - number = component.decimalValue; + number = component.unsignedLongLongValue; - if (number < 0 || number > UINT8_MAX) + if (number > UINT8_MAX) @throw [OFInvalidFormatException exception]; - addr = (addr << 8) | (number & 0xFF); + addr = (addr << 8) | ((uint32_t)number & 0xFF); } addrIn->sin_addr.s_addr = OF_BSWAP32_IF_LE(addr); objc_autoreleasePoolPop(pool); @@ -401,17 +401,17 @@ } static uint16_t parseIPv6Component(OFString *component) { - uintmax_t number; + unsigned long long number; if ([component indexOfCharacterFromSet: [OFCharacterSet whitespaceCharacterSet]] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; - number = component.hexadecimalValue; + number = [component unsignedLongLongValueWithBase: 16]; if (number > UINT16_MAX) @throw [OFInvalidFormatException exception]; return (uint16_t)number; @@ -499,15 +499,19 @@ } of_socket_address_t of_socket_address_parse_ip(OFString *IP, uint16_t port) { + of_socket_address_t ret; + @try { - return of_socket_address_parse_ipv6(IP, port); + ret = of_socket_address_parse_ipv6(IP, port); } @catch (OFInvalidFormatException *e) { - return of_socket_address_parse_ipv4(IP, port); + ret = of_socket_address_parse_ipv4(IP, port); } + + return ret; } of_socket_address_t of_socket_address_ipx(const unsigned char node[IPX_NODE_LEN], uint32_t network, uint16_t port) Index: tests/Info.plist.in ================================================================== --- tests/Info.plist.in +++ tests/Info.plist.in @@ -11,13 +11,13 @@ CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleVersion - @PACKAGE_VERSION@ + @BUNDLE_VERSION@ CFBundleShortVersionString - @PACKAGE_VERSION@ + @BUNDLE_SHORT_VERSION@ LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -9,12 +9,12 @@ DISTCLEAN = Info.plist PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ + OFASN1DERParsingTests.m \ OFASN1DERRepresentationTests.m \ - OFASN1DERValueTests.m \ OFArrayTests.m \ ${OF_BLOCK_TESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDateTests.m \ @@ -128,14 +128,14 @@ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ASAN_OPTIONS=allocator_may_return_null=1 \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ - rm -f objfw.so.${OBJFW_LIB_MAJOR_MINOR} objfw.dll; \ + rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} objfw.dll; \ rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ - rm -f objfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} objfwrt.dll; \ + rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} objfwrt.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT run-on-ios: all if [ -z "${IOS_HOST}" ]; then \ ADDED tests/OFASN1DERParsingTests.m Index: tests/OFASN1DERParsingTests.m ================================================================== --- tests/OFASN1DERParsingTests.m +++ tests/OFASN1DERParsingTests.m @@ -0,0 +1,483 @@ +/* + * 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 = @"OFData+ASN1DERParsing"; + +@implementation TestsAppDelegate (OFASN1DERParsingTests) +- (void)ASN1DERParsingTests +{ + void *pool = objc_autoreleasePoolPush(); + OFASN1BitString *bitString; + OFArray *array; + OFSet *set; + OFEnumerator *enumerator; + + /* Boolean */ + TEST(@"Parsing of boolean", + ![[[OFData dataWithItems: "\x01\x01\x00" + count: 3] objectByParsingASN1DER] + booleanValue] && + [[[OFData dataWithItems: "\x01\x01\xFF" + count: 3] objectByParsingASN1DER] booleanValue]) + + EXPECT_EXCEPTION(@"Detection of invalid boolean #1", + OFInvalidFormatException, + [[OFData dataWithItems: "\x01\x01\x01" + count: 3] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid boolean #2", + OFInvalidFormatException, + [[OFData dataWithItems: "\x01\x02\x00\x00" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid boolean #3", + OFInvalidFormatException, + [[OFData dataWithItems: "\x01\x00" + count: 2] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated boolean", + OFTruncatedDataException, + [[OFData dataWithItems: "\x01\x01" + count: 2] objectByParsingASN1DER]) + + /* Integer */ + TEST(@"Parsing of integer", + [[[OFData dataWithItems: "\x02\x00" + count: 2] objectByParsingASN1DER] + longLongValue] == 0 && + [[[OFData dataWithItems: "\x02\x01\x01" + count: 3] objectByParsingASN1DER] + longLongValue] == 1 && + [[[OFData dataWithItems: "\x02\x02\x01\x04" + count: 4] objectByParsingASN1DER] + longLongValue] == 260 && + [[[OFData dataWithItems: "\x02\x01\xFF" + count: 3] objectByParsingASN1DER] + longLongValue] == -1 && + [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00" + count: 5] objectByParsingASN1DER] + longLongValue] == -65536 && + (unsigned long long)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF" + "\xFF" + count: 11] + objectByParsingASN1DER] longLongValue] == ULLONG_MAX) + + EXPECT_EXCEPTION(@"Detection of invalid integer #1", + OFInvalidFormatException, + [[OFData dataWithItems: "\x02\x02\x00\x00" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid integer #2", + OFInvalidFormatException, + [[OFData dataWithItems: "\x02\x02\x00\x7F" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid integer #3", + OFInvalidFormatException, + [[OFData dataWithItems: "\x02\x02\xFF\x80" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range integer", + OFOutOfRangeException, + [[OFData dataWithItems: "\x02\x09\x01" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated integer", + OFTruncatedDataException, + [[OFData dataWithItems: "\x02\x02\x00" + count: 3] objectByParsingASN1DER]) + + /* Bit string */ + TEST(@"Parsing of bit string", + (bitString = [[OFData dataWithItems: "\x03\x01\x00" + count: 3] objectByParsingASN1DER]) && + [bitString.bitStringValue isEqual: [OFData dataWithItems: "" + count: 0]] && + bitString.bitStringLength == 0 && + (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80" + count: 15] objectByParsingASN1DER]) && + [bitString.bitStringValue + isEqual: [OFData dataWithItems: "Hello World\x80" + count: 12]] && + bitString.bitStringLength == 95 && + (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxx" + count: 131] objectByParsingASN1DER]) && + [bitString.bitStringValue + isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxx" + count: 127]] && + bitString.bitStringLength == 127 * 8) + + EXPECT_EXCEPTION(@"Detection of invalid bit string #1", + OFInvalidFormatException, + [[OFData dataWithItems: "\x03\x00" + count: 2] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid bit string #2", + OFInvalidFormatException, + [[OFData dataWithItems: "\x03\x01\x01" + count: 3] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range bit string", + OFOutOfRangeException, + [[OFData dataWithItems: "\x03\x89" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated bit string", + OFTruncatedDataException, + [[OFData dataWithItems: "\x03\x01" + count: 2] objectByParsingASN1DER]) + + /* Octet string */ + TEST(@"Parsing of octet string", + [[[[OFData dataWithItems: "\x04\x0CHello World!" + count: 14] objectByParsingASN1DER] + octetStringValue] isEqual: [OFData dataWithItems: "Hello World!" + count: 12]] && + [[[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxx" + count: 131] objectByParsingASN1DER] + octetStringValue] isEqual: + [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + count: 128]]) + + EXPECT_EXCEPTION(@"Detection of out of range octet string", + OFOutOfRangeException, + [[OFData dataWithItems: "\x04\x89" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated octet string", + OFTruncatedDataException, + [[OFData dataWithItems: "\x04\x01" + count: 2] objectByParsingASN1DER]) + + /* Null */ + TEST(@"Parsing of null", + [[[OFData dataWithItems: "\x05\x00" + count: 2] objectByParsingASN1DER] + isEqual: [OFNull null]]) + + EXPECT_EXCEPTION(@"Detection of invalid null", + OFInvalidFormatException, + [[OFData dataWithItems: "\x05\x01\x00" + count: 3] objectByParsingASN1DER]) + + /* Object Identifier */ + TEST(@"Parsing of Object Identifier", + (array = [[[OFData dataWithItems: "\x06\x01\x27" + count: 3] objectByParsingASN1DER] + subidentifiers]) && array.count == 2 && + [[array objectAtIndex: 0] unsignedLongLongValue] == 0 && + [[array objectAtIndex: 1] unsignedLongLongValue] == 39 && + (array = [[[OFData dataWithItems: "\x06\x01\x4F" + count: 3] objectByParsingASN1DER] + subidentifiers]) && array.count == 2 && + [[array objectAtIndex: 0] unsignedLongLongValue] == 1 && + [[array objectAtIndex: 1] unsignedLongLongValue] == 39 && + (array = [[[OFData dataWithItems: "\x06\x02\x88\x37" + count: 4] objectByParsingASN1DER] + subidentifiers]) && array.count == 2 && + [[array objectAtIndex: 0] unsignedLongLongValue] == 2 && + [[array objectAtIndex: 1] unsignedLongLongValue] == 999 && + (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D" + "\x01\x01\x0B" + count: 11] objectByParsingASN1DER] + subidentifiers]) && array.count == 7 && + [[array objectAtIndex: 0] unsignedLongLongValue] == 1 && + [[array objectAtIndex: 1] unsignedLongLongValue] == 2 && + [[array objectAtIndex: 2] unsignedLongLongValue] == 840 && + [[array objectAtIndex: 3] unsignedLongLongValue] == 113549 && + [[array objectAtIndex: 4] unsignedLongLongValue] == 1 && + [[array objectAtIndex: 5] unsignedLongLongValue] == 1 && + [[array objectAtIndex: 6] unsignedLongLongValue] == 11) + + EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1", + OFInvalidFormatException, + [[OFData dataWithItems: "\x06\x01\x81" + count: 3] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2", + OFInvalidFormatException, + [[OFData dataWithItems: "\x06\x02\x80\x01" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range Object Identifier", + OFOutOfRangeException, + [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x7F" + count: 12] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated Object Identifier", + OFTruncatedDataException, + [[OFData dataWithItems: "\x06\x02\x00" + count: 3] objectByParsingASN1DER]) + + /* Enumerated */ + TEST(@"Parsing of enumerated", + [[[OFData dataWithItems: "\x0A\x00" + count: 2] objectByParsingASN1DER] longLongValue] == + 0 && + [[[OFData dataWithItems: "\x0A\x01\x01" + count: 3] objectByParsingASN1DER] longLongValue] == + 1 && + [[[OFData dataWithItems: "\x0A\x02\x01\x04" + count: 4] objectByParsingASN1DER] longLongValue] == + 260 && + [[[OFData dataWithItems: "\x0A\x01\xFF" + count: 3] objectByParsingASN1DER] longLongValue] == + -1 && + [[[OFData dataWithItems: "\x0A\x03\xFF\x00\x00" + count: 5] objectByParsingASN1DER] longLongValue] == + -65536 && + (unsigned long long)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF" + "\xFF" + count: 11] + objectByParsingASN1DER] longLongValue] == ULLONG_MAX) + + EXPECT_EXCEPTION(@"Detection of invalid enumerated #1", + OFInvalidFormatException, + [[OFData dataWithItems: "\x0A\x02\x00\x00" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid enumerated #2", + OFInvalidFormatException, + [[OFData dataWithItems: "\x0A\x02\x00\x7F" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid enumerated #3", + OFInvalidFormatException, + [[OFData dataWithItems: "\x0A\x02\xFF\x80" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range enumerated", + OFOutOfRangeException, + [[OFData dataWithItems: "\x0A\x09\x01" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated enumerated", + OFTruncatedDataException, + [[OFData dataWithItems: "\x0A\x02\x00" + count: 3] objectByParsingASN1DER]) + + /* UTF-8 string */ + TEST(@"Parsing of UTF-8 string", + [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!" + count: 16] objectByParsingASN1DER] + UTF8StringValue] isEqual: @"Hällo Wörld!"] && + [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxx" + count: 131] objectByParsingASN1DER] + UTF8StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + @"xxxxxxxxxxx"]) + + EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string", + OFOutOfRangeException, + [[OFData dataWithItems: "\x0C\x89" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string", + OFTruncatedDataException, + [[OFData dataWithItems: "\x0C\x01" + count: 2] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated length", + OFTruncatedDataException, + [[OFData dataWithItems: "\x0C\x83\x01\x01" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1", + OFInvalidFormatException, + [[OFData dataWithItems: "\x0C\x81\x7F" + count: 3] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2", + OFInvalidFormatException, + [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxx" + count: 132] objectByParsingASN1DER]) + + /* Sequence */ + TEST(@"Parsing of sequence", + (array = [[OFData dataWithItems: "\x30\x00" + count: 2] objectByParsingASN1DER]) && + [array isKindOfClass: [OFArray class]] && array.count == 0 && + (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test" + count: 11] objectByParsingASN1DER]) && + [array isKindOfClass: [OFArray class]] && array.count == 2 && + [[array objectAtIndex: 0] longLongValue] == 123 && + [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"]) + + EXPECT_EXCEPTION(@"Detection of truncated sequence #1", + OFTruncatedDataException, + [[OFData dataWithItems: "\x30\x01" + count: 2] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated sequence #2", + OFTruncatedDataException, + [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00" + count: 7] objectByParsingASN1DER]) + + /* Set */ + TEST(@"Parsing of set", + (set = [[OFData dataWithItems: "\x31\x00" + count: 2] objectByParsingASN1DER]) && + [set isKindOfClass: [OFSet class]] && set.count == 0 && + (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test" + count: 11] objectByParsingASN1DER]) && + [set isKindOfClass: [OFSet class]] && set.count == 2 && + (enumerator = [set objectEnumerator]) && + [[enumerator nextObject] longLongValue] == 123 && + [[[enumerator nextObject] stringValue] isEqual: @"Test"]) + + EXPECT_EXCEPTION(@"Detection of invalid set", + OFInvalidFormatException, + [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01" + count: 8] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated set #1", + OFTruncatedDataException, + [[OFData dataWithItems: "\x31\x01" + count: 2] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated set #2", + OFTruncatedDataException, + [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00" + count: 7] objectByParsingASN1DER]) + + /* NumericString */ + TEST(@"Parsing of NumericString", + [[[[OFData dataWithItems: "\x12\x0B" "12345 67890" + count: 13] objectByParsingASN1DER] + numericStringValue] isEqual: @"12345 67890"] && + [[[[OFData dataWithItems: "\x12\x81\x80" "0000000000000000000000000" + "0000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000" + "00000000000000000000000" + count: 131] objectByParsingASN1DER] + numericStringValue] isEqual: @"000000000000000000000000000000000000" + @"000000000000000000000000000000000000" + @"000000000000000000000000000000000000" + @"00000000000000000000"]) + + EXPECT_EXCEPTION(@"Detection of invalid NumericString", + OFInvalidEncodingException, + [[OFData dataWithItems: "\x12\x02." + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range NumericString", + OFOutOfRangeException, + [[OFData dataWithItems: "\x12\x89" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated NumericString", + OFTruncatedDataException, + [[OFData dataWithItems: "\x12\x01" + count: 2] objectByParsingASN1DER]) + + /* PrintableString */ + TEST(@"Parsing of PrintableString", + [[[[OFData dataWithItems: "\x13\x0CHello World." + count: 14] objectByParsingASN1DER] + printableStringValue] isEqual: @"Hello World."] && + [[[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnop" + "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()" + "+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEF" + "GHIJKLMNOPQRSTUVWXYZ" + count: 131] objectByParsingASN1DER] + printableStringValue] isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuv" + @"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()" + @"+,-./:=?abcdefghijklmnopqrstuvwxyz" + @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"]) + + EXPECT_EXCEPTION(@"Detection of invalid PrintableString", + OFInvalidEncodingException, + [[OFData dataWithItems: "\x13\x02;" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range PrintableString", + OFOutOfRangeException, + [[OFData dataWithItems: "\x13\x89" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated PrintableString", + OFTruncatedDataException, + [[OFData dataWithItems: "\x13\x01" + count: 2] objectByParsingASN1DER]) + + /* IA5String */ + TEST(@"Parsing of IA5String", + [[[[OFData dataWithItems: "\x16\x0CHello World!" + count: 14] objectByParsingASN1DER] + IA5StringValue] isEqual: @"Hello World!"] && + [[[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxx" + count: 131] objectByParsingASN1DER] + IA5StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + @"xxxxxxxx"]) + + EXPECT_EXCEPTION(@"Detection of invalid IA5String", + OFInvalidEncodingException, + [[OFData dataWithItems: "\x16\x02ä" + count: 4] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of out of range IA5String", + OFOutOfRangeException, + [[OFData dataWithItems: "\x16\x89" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01" + count: 11] objectByParsingASN1DER]) + + EXPECT_EXCEPTION(@"Detection of truncated IA5String", + OFTruncatedDataException, + [[OFData dataWithItems: "\x16\x01" + count: 2] objectByParsingASN1DER]) + + objc_autoreleasePoolPop(pool); +} +@end DELETED tests/OFASN1DERValueTests.m Index: tests/OFASN1DERValueTests.m ================================================================== --- tests/OFASN1DERValueTests.m +++ tests/OFASN1DERValueTests.m @@ -1,437 +0,0 @@ -/* - * 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 = @"OFData+ASN1DERValue"; - -@implementation TestsAppDelegate (OFASN1DERValueTests) -- (void)ASN1DERValueTests -{ - void *pool = objc_autoreleasePoolPush(); - OFASN1BitString *bitString; - OFArray *array; - OFSet *set; - OFEnumerator *enumerator; - - /* Boolean */ - TEST(@"Parsing of boolean", - ![[[OFData dataWithItems: "\x01\x01\x00" - count: 3] ASN1DERValue] booleanValue] && - [[[OFData dataWithItems: "\x01\x01\xFF" - count: 3] ASN1DERValue] booleanValue]) - - EXPECT_EXCEPTION(@"Detection of invalid boolean #1", - OFInvalidFormatException, [[OFData dataWithItems: "\x01\x01\x01" - count: 3] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid boolean #2", - OFInvalidFormatException, [[OFData dataWithItems: "\x01\x02\x00\x00" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid boolean #3", - OFInvalidFormatException, [[OFData dataWithItems: "\x01\x00" - count: 2] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated boolean", - OFTruncatedDataException, [[OFData dataWithItems: "\x01\x01" - count: 2] ASN1DERValue]) - - /* Integer */ - TEST(@"Parsing of integer", - [[[OFData dataWithItems: "\x02\x00" - count: 2] ASN1DERValue] integerValue] == 0 && - [[[OFData dataWithItems: "\x02\x01\x01" - count: 3] ASN1DERValue] integerValue] == 1 && - [[[OFData dataWithItems: "\x02\x02\x01\x04" - count: 4] ASN1DERValue] integerValue] == 260 && - [[[OFData dataWithItems: "\x02\x01\xFF" - count: 3] ASN1DERValue] integerValue] == -1 && - [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00" - count: 5] ASN1DERValue] integerValue] == -65536 && - (uintmax_t)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF\xFF\xFF" - "\xFF\xFF\xFF\xFF" - count: 11] ASN1DERValue] - integerValue] == UINTMAX_MAX) - - EXPECT_EXCEPTION(@"Detection of invalid integer #1", - OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x00" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid integer #2", - OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x7F" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid integer #3", - OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\xFF\x80" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range integer", - OFOutOfRangeException, - [[OFData dataWithItems: "\x02\x09\x01" - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated integer", - OFTruncatedDataException, [[OFData dataWithItems: "\x02\x02\x00" - count: 3] ASN1DERValue]) - - /* Bit string */ - TEST(@"Parsing of bit string", - (bitString = [[OFData dataWithItems: "\x03\x01\x00" - count: 3] ASN1DERValue]) && - [bitString.bitStringValue isEqual: [OFData dataWithItems: "" - count: 0]] && - bitString.bitStringLength == 0 && - (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80" - count: 15] ASN1DERValue]) && - [bitString.bitStringValue - isEqual: [OFData dataWithItems: "Hello World\x80" - count: 12]] && - bitString.bitStringLength == 95 && - (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxx" - count: 131] ASN1DERValue]) && - [bitString.bitStringValue - isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxx" - count: 127]] && - bitString.bitStringLength == 127 * 8) - - EXPECT_EXCEPTION(@"Detection of invalid bit string #1", - OFInvalidFormatException, [[OFData dataWithItems: "\x03\x00" - count: 2] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid bit string #2", - OFInvalidFormatException, [[OFData dataWithItems: "\x03\x01\x01" - count: 3] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range bit string", - OFOutOfRangeException, - [[OFData dataWithItems: "\x03\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated bit string", - OFTruncatedDataException, [[OFData dataWithItems: "\x03\x01" - count: 2] ASN1DERValue]) - - /* Octet string */ - TEST(@"Parsing of octet string", - [[[[OFData dataWithItems: "\x04\x0CHello World!" - count: 14] ASN1DERValue] octetStringValue] - isEqual: [OFData dataWithItems: "Hello World!" - count: 12]] && - [[[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxx" - count: 131] ASN1DERValue] octetStringValue] - isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxx" - count: 128]]) - - EXPECT_EXCEPTION(@"Detection of out of range octet string", - OFOutOfRangeException, - [[OFData dataWithItems: "\x04\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated octet string", - OFTruncatedDataException, [[OFData dataWithItems: "\x04\x01" - count: 2] ASN1DERValue]) - - /* Null */ - TEST(@"Parsing of null", - [[[OFData dataWithItems: "\x05\x00" - count: 2] ASN1DERValue] isEqual: [OFNull null]]) - - EXPECT_EXCEPTION(@"Detection of invalid null", - OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00" - count: 3] ASN1DERValue]) - - /* Object Identifier */ - TEST(@"Parsing of Object Identifier", - (array = [[[OFData dataWithItems: "\x06\x01\x27" - count: 3] ASN1DERValue] - subidentifiers]) && array.count == 2 && - [[array objectAtIndex: 0] uIntMaxValue] == 0 && - [[array objectAtIndex: 1] uIntMaxValue] == 39 && - (array = [[[OFData dataWithItems: "\x06\x01\x4F" - count: 3] ASN1DERValue] - subidentifiers]) && array.count == 2 && - [[array objectAtIndex: 0] uIntMaxValue] == 1 && - [[array objectAtIndex: 1] uIntMaxValue] == 39 && - (array = [[[OFData dataWithItems: "\x06\x02\x88\x37" - count: 4] ASN1DERValue] - subidentifiers]) && array.count == 2 && - [[array objectAtIndex: 0] uIntMaxValue] == 2 && - [[array objectAtIndex: 1] uIntMaxValue] == 999 && - (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D" - "\x01\x01\x0B" - count: 11] ASN1DERValue] - subidentifiers]) && array.count == 7 && - [[array objectAtIndex: 0] uIntMaxValue] == 1 && - [[array objectAtIndex: 1] uIntMaxValue] == 2 && - [[array objectAtIndex: 2] uIntMaxValue] == 840 && - [[array objectAtIndex: 3] uIntMaxValue] == 113549 && - [[array objectAtIndex: 4] uIntMaxValue] == 1 && - [[array objectAtIndex: 5] uIntMaxValue] == 1 && - [[array objectAtIndex: 6] uIntMaxValue] == 11) - - EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1", - OFInvalidFormatException, [[OFData dataWithItems: "\x06\x01\x81" - count: 3] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2", - OFInvalidFormatException, [[OFData dataWithItems: "\x06\x02\x80\x01" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range Object Identifier", - OFOutOfRangeException, - [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - "\xFF\x7F" - count: 12] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated Object Identifier", - OFTruncatedDataException, [[OFData dataWithItems: "\x06\x02\x00" - count: 3] ASN1DERValue]) - - /* Enumerated */ - TEST(@"Parsing of enumerated", - [[[OFData dataWithItems: "\x0A\x00" - count: 2] ASN1DERValue] integerValue] == 0 && - [[[OFData dataWithItems: "\x0A\x01\x01" - count: 3] ASN1DERValue] integerValue] == 1 && - [[[OFData dataWithItems: "\x0A\x02\x01\x04" - count: 4] ASN1DERValue] integerValue] == 260 && - [[[OFData dataWithItems: "\x0A\x01\xFF" - count: 3] ASN1DERValue] integerValue] == -1 && - [[[OFData dataWithItems: "\x0A\x03\xFF\x00\x00" - count: 5] ASN1DERValue] integerValue] == -65536 && - (uintmax_t)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF\xFF\xFF" - "\xFF\xFF\xFF\xFF" - count: 11] ASN1DERValue] - integerValue] == UINTMAX_MAX) - - EXPECT_EXCEPTION(@"Detection of invalid enumerated #1", - OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x00" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid enumerated #2", - OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x7F" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid enumerated #3", - OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\xFF\x80" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range enumerated", - OFOutOfRangeException, - [[OFData dataWithItems: "\x0A\x09\x01" - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated enumerated", - OFTruncatedDataException, [[OFData dataWithItems: "\x0A\x02\x00" - count: 3] ASN1DERValue]) - - /* UTF-8 string */ - TEST(@"Parsing of UTF-8 string", - [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!" - count: 16] ASN1DERValue] UTF8StringValue] - isEqual: @"Hällo Wörld!"] && - [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxx" - count: 131] ASN1DERValue] UTF8StringValue] - isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxx"]) - - EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string", - OFOutOfRangeException, - [[OFData dataWithItems: "\x0C\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string", - OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x01" - count: 2] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated length", - OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x83\x01\x01" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1", - OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x81\x7F" - count: 3] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxx" - count: 132] ASN1DERValue]) - - /* Sequence */ - TEST(@"Parsing of sequence", - (array = [[OFData dataWithItems: "\x30\x00" - count: 2] ASN1DERValue]) && - [array isKindOfClass: [OFArray class]] && array.count == 0 && - (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test" - count: 11] ASN1DERValue]) && - [array isKindOfClass: [OFArray class]] && array.count == 2 && - [[array objectAtIndex: 0] integerValue] == 123 && - [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"]) - - EXPECT_EXCEPTION(@"Detection of truncated sequence #1", - OFTruncatedDataException, [[OFData dataWithItems: "\x30\x01" - count: 2] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated sequence #2", - OFTruncatedDataException, - [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00" - count: 7] ASN1DERValue]) - - /* Set */ - TEST(@"Parsing of set", - (set = [[OFData dataWithItems: "\x31\x00" - count: 2] ASN1DERValue]) && - [set isKindOfClass: [OFSet class]] && set.count == 0 && - (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test" - count: 11] ASN1DERValue]) && - [set isKindOfClass: [OFSet class]] && set.count == 2 && - (enumerator = [set objectEnumerator]) && - [[enumerator nextObject] integerValue] == 123 && - [[[enumerator nextObject] stringValue] isEqual: @"Test"]) - - EXPECT_EXCEPTION(@"Detection of invalid set", - OFInvalidFormatException, - [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01" - count: 8] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated set #1", - OFTruncatedDataException, [[OFData dataWithItems: "\x31\x01" - count: 2] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated set #2", - OFTruncatedDataException, - [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00" - count: 7] ASN1DERValue]) - - /* NumericString */ - TEST(@"Parsing of NumericString", - [[[[OFData dataWithItems: "\x12\x0B" "12345 67890" - count: 13] ASN1DERValue] numericStringValue] - isEqual: @"12345 67890"] && - [[[[OFData dataWithItems: "\x12\x81\x80" "0000000000000000000000000" - "0000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000" - "00000000000000000000000" - count: 131] ASN1DERValue] numericStringValue] - isEqual: @"00000000000000000000000000000000000000000000000000000000" - @"00000000000000000000000000000000000000000000000000000000" - @"0000000000000000"]) - - EXPECT_EXCEPTION(@"Detection of invalid NumericString", - OFInvalidEncodingException, - [[OFData dataWithItems: "\x12\x02." - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range NumericString", - OFOutOfRangeException, - [[OFData dataWithItems: "\x12\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated NumericString", - OFTruncatedDataException, [[OFData dataWithItems: "\x12\x01" - count: 2] ASN1DERValue]) - - /* PrintableString */ - TEST(@"Parsing of PrintableString", - [[[[OFData dataWithItems: "\x13\x0CHello World." - count: 14] ASN1DERValue] printableStringValue] - isEqual: @"Hello World."] && - [[[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnop" - "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()" - "+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEF" - "GHIJKLMNOPQRSTUVWXYZ" - count: 131] ASN1DERValue] printableStringValue] - isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR" - @"STUVWXYZ '()+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHIJ" - @"KLMNOPQRSTUVWXYZ"]) - - EXPECT_EXCEPTION(@"Detection of invalid PrintableString", - OFInvalidEncodingException, - [[OFData dataWithItems: "\x13\x02;" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range PrintableString", - OFOutOfRangeException, - [[OFData dataWithItems: "\x13\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated PrintableString", - OFTruncatedDataException, [[OFData dataWithItems: "\x13\x01" - count: 2] ASN1DERValue]) - - /* IA5String */ - TEST(@"Parsing of IA5String", - [[[[OFData dataWithItems: "\x16\x0CHello World!" - count: 14] ASN1DERValue] IA5StringValue] - isEqual: @"Hello World!"] && - [[[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxx" - count: 131] ASN1DERValue] IA5StringValue] - isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxx"]) - - EXPECT_EXCEPTION(@"Detection of invalid IA5String", - OFInvalidEncodingException, - [[OFData dataWithItems: "\x16\x02ä" - count: 4] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of out of range IA5String", - OFOutOfRangeException, - [[OFData dataWithItems: "\x16\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] ASN1DERValue]) - - EXPECT_EXCEPTION(@"Detection of truncated IA5String", - OFTruncatedDataException, [[OFData dataWithItems: "\x16\x01" - count: 2] ASN1DERValue]) - - objc_autoreleasePoolPop(pool); -} -@end Index: tests/OFArrayTests.m ================================================================== --- tests/OFArrayTests.m +++ tests/OFArrayTests.m @@ -420,14 +420,14 @@ #endif TEST(@"-[valueForKey:]", [[[arrayClass arrayWithObjects: @"foo", @"bar", @"quxqux", nil] valueForKey: @"length"] isEqual: - [arrayClass arrayWithObjects: [OFNumber numberWithSize: 3], - [OFNumber numberWithSize: 3], [OFNumber numberWithSize: 6], nil]] && + [arrayClass arrayWithObjects: [OFNumber numberWithInt: 3], + [OFNumber numberWithInt: 3], [OFNumber numberWithInt: 6], nil]] && [[[arrayClass arrayWithObjects: @"1", @"2", nil] - valueForKey: @"@count"] isEqual: [OFNumber numberWithSize: 2]]) + valueForKey: @"@count"] isEqual: [OFNumber numberWithInt: 2]]) m[0] = [mutableArrayClass arrayWithObjects: [OFMutableURL URLWithString: @"http://foo.bar/"], [OFMutableURL URLWithString: @"http://bar.qux/"], [OFMutableURL URLWithString: @"http://qux.quxqux/"], nil]; Index: tests/OFDNSResolverTests.m ================================================================== --- tests/OFDNSResolverTests.m +++ tests/OFDNSResolverTests.m @@ -24,11 +24,11 @@ { void *pool = objc_autoreleasePoolPush(); OFDNSResolver *resolver = [OFDNSResolver resolver]; OFMutableString *staticHosts = [OFMutableString string]; - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; for (OFString *host in resolver.staticHosts) { OFString *IPs; if (staticHosts.length > 0) Index: tests/OFDictionaryTests.m ================================================================== --- tests/OFDictionaryTests.m +++ tests/OFDictionaryTests.m @@ -180,11 +180,11 @@ [mutDict objectForKey: @"key3"] == nil) TEST(@"-[valueForKey:]", [[mutDict valueForKey: keys[0]] isEqual: values[0]] && [[mutDict valueForKey: @"@count"] isEqual: - [OFNumber numberWithSize: 2]]) + [OFNumber numberWithInt: 2]]) EXPECT_EXCEPTION(@"Catching -[setValue:forKey:] on immutable " @"dictionary", OFUndefinedKeyException, [[dictionaryClass dictionary] setValue: @"x" forKey: @"x"]) Index: tests/OFIPXSocketTests.m ================================================================== --- tests/OFIPXSocketTests.m +++ tests/OFIPXSocketTests.m @@ -38,17 +38,17 @@ R(address1 = [sock bindToPort: 0 packetType: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFIPXSocket] -[bindToPort:packetType:]: " @"IPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFIPXSocket] -[bindToPort:packetType:]: " @"IPX not configured, skipping tests"]; break; default: Index: tests/OFJSONTests.m ================================================================== --- tests/OFJSONTests.m +++ tests/OFJSONTests.m @@ -36,11 +36,11 @@ @"foo", [OFNumber numberWithBool: false], nil], nil]; - TEST(@"-[JSONValue] #1", [s.JSONValue isEqual: d]) + TEST(@"-[objectByParsingJSON] #1", [s.objectByParsingJSON isEqual: d]) TEST(@"-[JSONRepresentation]", [[d JSONRepresentation] isEqual: @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"b\\na\\r\"}"]) TEST(@"OF_JSON_REPRESENTATION_PRETTY", @@ -50,22 +50,22 @@ TEST(@"OF_JSON_REPRESENTATION_JSON5", [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_JSON5] isEqual: @"{x:[0.5,15,null,\"foo\",false],foo:\"b\\\na\\r\"}"]) - EXPECT_EXCEPTION(@"-[JSONValue] #2", OFInvalidJSONException, - [@"{" JSONValue]) - EXPECT_EXCEPTION(@"-[JSONValue] #3", OFInvalidJSONException, - [@"]" JSONValue]) - EXPECT_EXCEPTION(@"-[JSONValue] #4", OFInvalidJSONException, - [@"bar" JSONValue]) - EXPECT_EXCEPTION(@"-[JSONValue] #5", OFInvalidJSONException, - [@"[\"a\" \"b\"]" JSONValue]) - - TEST(@"-[JSONValue] #6", - [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" - .JSONValue isEqual: [OFArray arrayWithObject: + EXPECT_EXCEPTION(@"-[objectByParsingJSON] #2", OFInvalidJSONException, + [@"{" objectByParsingJSON]) + EXPECT_EXCEPTION(@"-[objectByParsingJSON] #3", OFInvalidJSONException, + [@"]" objectByParsingJSON]) + EXPECT_EXCEPTION(@"-[objectByParsingJSON] #4", OFInvalidJSONException, + [@"bar" objectByParsingJSON]) + EXPECT_EXCEPTION(@"-[objectByParsingJSON] #5", OFInvalidJSONException, + [@"[\"a\" \"b\"]" objectByParsingJSON]) + + TEST(@"-[objectByParsingJSON] #6", + [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + .objectByParsingJSON isEqual: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: @@ -79,12 +79,12 @@ [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFArray arrayWithObject: [OFDictionary dictionary]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]) - EXPECT_EXCEPTION(@"-[JSONValue] #7", OFInvalidJSONException, + EXPECT_EXCEPTION(@"-[objectByParsingJSON] #7", OFInvalidJSONException, [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" - JSONValue]) + objectByParsingJSON]) objc_autoreleasePoolPop(pool); } @end Index: tests/OFLocaleTests.m ================================================================== --- tests/OFLocaleTests.m +++ tests/OFLocaleTests.m @@ -22,11 +22,11 @@ @implementation TestsAppDelegate (OFLocaleTests) - (void)localeTests { void *pool = objc_autoreleasePoolPush(); - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeFormat: @"[OFLocale] Language: %@\n", [OFLocale language]]; [of_stdout writeFormat: @"[OFLocale] Territory: %@\n", Index: tests/OFMethodSignatureTests.m ================================================================== --- tests/OFMethodSignatureTests.m +++ tests/OFMethodSignatureTests.m @@ -75,11 +75,11 @@ - (void)methodSignatureTests { void *pool = objc_autoreleasePoolPush(); OFMethodSignature *ms; - TEST(@"-[:signatureWithObjCTypes:] #1", + TEST(@"-[signatureWithObjCTypes:] #1", (ms = [OFMethodSignature signatureWithObjCTypes: "i28@0:8S16*20"]) && ms.numberOfArguments == 4 && strcmp(ms.methodReturnType, "i") == 0 && strcmp([ms argumentTypeAtIndex: 0], "@") == 0 && strcmp([ms argumentTypeAtIndex: 1], ":") == 0 && @@ -126,11 +126,12 @@ TEST(@"of_sizeof_type_encoding() #2", of_sizeof_type_encoding(@encode(struct test2_struct)) == sizeof(struct test2_struct)) -#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) +#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) && \ + OF_GCC_VERSION >= 402 TEST(@"of_sizeof_type_encoding() #3", of_sizeof_type_encoding(@encode(struct test3_struct)) == sizeof(struct test3_struct)) #endif @@ -152,11 +153,12 @@ TEST(@"of_alignof_type_encoding() #2", of_alignof_type_encoding(@encode(struct test2_struct)) == OF_ALIGNOF(struct test2_struct)) -#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) +#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) && \ + OF_GCC_VERSION >= 402 TEST(@"of_alignof_type_encoding() #3", of_alignof_type_encoding(@encode(struct test3_struct)) == OF_ALIGNOF(struct test3_struct)) #endif Index: tests/OFNumberTests.m ================================================================== --- tests/OFNumberTests.m +++ tests/OFNumberTests.m @@ -25,20 +25,70 @@ - (void)numberTests { void *pool = objc_autoreleasePoolPush(); OFNumber *num; - TEST(@"+[numberWithIntMax:]", - (num = [OFNumber numberWithIntMax: 123456789])) + TEST(@"+[numberWithLongLong:]", + (num = [OFNumber numberWithLongLong: 123456789])) TEST(@"-[isEqual:]", - [num isEqual: [OFNumber numberWithUInt32: 123456789]]) + [num isEqual: [OFNumber numberWithLong: 123456789]]) TEST(@"-[hash]", num.hash == 0x82D8BC42) TEST(@"-[charValue]", num.charValue == 21) TEST(@"-[doubleValue]", num.doubleValue == 123456789.L) + + TEST(@"signed char minimum & maximum unmodified", + (num = [OFNumber numberWithChar: SCHAR_MIN]) && + num.charValue == SCHAR_MIN && + (num = [OFNumber numberWithChar: SCHAR_MAX]) && + num.charValue == SCHAR_MAX) + + TEST(@"short minimum & maximum unmodified", + (num = [OFNumber numberWithShort: SHRT_MIN]) && + num.shortValue == SHRT_MIN && + (num = [OFNumber numberWithShort: SHRT_MAX]) && + num.shortValue == SHRT_MAX) + + TEST(@"int minimum & maximum unmodified", + (num = [OFNumber numberWithInt: INT_MIN]) && + num.intValue == INT_MIN && + (num = [OFNumber numberWithInt: INT_MAX]) && + num.intValue == INT_MAX) + + TEST(@"long minimum & maximum unmodified", + (num = [OFNumber numberWithLong: LONG_MIN]) && + num.longValue == LONG_MIN && + (num = [OFNumber numberWithLong: LONG_MAX]) && + num.longValue == LONG_MAX) + + TEST(@"long long minimum & maximum unmodified", + (num = [OFNumber numberWithLongLong: LLONG_MIN]) && + num.longLongValue == LLONG_MIN && + (num = [OFNumber numberWithLongLong: LLONG_MAX]) && + num.longLongValue == LLONG_MAX) + + TEST(@"unsigned char maximum unmodified", + (num = [OFNumber numberWithUnsignedChar: UCHAR_MAX]) && + num.unsignedCharValue == UCHAR_MAX) + + TEST(@"unsigned short maximum unmodified", + (num = [OFNumber numberWithUnsignedShort: USHRT_MAX]) && + num.unsignedShortValue == USHRT_MAX) + + TEST(@"unsigned int maximum unmodified", + (num = [OFNumber numberWithUnsignedInt: UINT_MAX]) && + num.unsignedIntValue == UINT_MAX) + + TEST(@"unsigned long maximum unmodified", + (num = [OFNumber numberWithUnsignedLong: ULONG_MAX]) && + num.unsignedLongValue == ULONG_MAX) + + TEST(@"unsigned long long maximum unmodified", + (num = [OFNumber numberWithUnsignedLongLong: ULLONG_MAX]) && + num.unsignedLongLongValue == ULLONG_MAX) objc_autoreleasePoolPop(pool); } @end Index: tests/OFPropertyListTests.m ================================================================== --- tests/OFPropertyListTests.m +++ tests/OFPropertyListTests.m @@ -64,56 +64,58 @@ [OFData dataWithItems: "World!" count: 6], [OFDate dateWithTimeIntervalSince1970: 1521030896], [OFNumber numberWithBool: true], [OFNumber numberWithBool: false], - [OFNumber numberWithFloat: 12.25], + [OFNumber numberWithFloat: 12.25f], [OFNumber numberWithInt: -10], nil]; - TEST(@"-[propertyListValue:] #1", - [PLIST1.propertyListValue isEqual: @"Hello"]) - - TEST(@"-[propertyListValue:] #2", - [PLIST2.propertyListValue isEqual: array]) - - TEST(@"-[propertyListValue:] #3", - [PLIST3.propertyListValue isEqual: + TEST(@"-[objectByParsingPropertyList:] #1", + [PLIST1.objectByParsingPropertyList isEqual: @"Hello"]) + + TEST(@"-[objectByParsingPropertyList:] #2", + [PLIST2.objectByParsingPropertyList isEqual: array]) + + TEST(@"-[objectByParsingPropertyList:] #3", + [PLIST3.objectByParsingPropertyList isEqual: [OFDictionary dictionaryWithKeysAndObjects: @"array", array, @"foo", @"bar", nil]]) - EXPECT_EXCEPTION(@"-[propertyListValue] detecting unsupported version", + EXPECT_EXCEPTION(@"Detecting unsupported version", OFUnsupportedVersionException, [[PLIST(@"") stringByReplacingOccurrencesOfString: @"1.0" withString: @"1.1"] - propertyListValue]) - - EXPECT_EXCEPTION( - @"-[propertyListValue] detecting invalid format #1", - OFInvalidFormatException, - [PLIST(@"") propertyListValue]) - - EXPECT_EXCEPTION( - @"-[propertyListValue] detecting invalid format #2", - OFInvalidFormatException, - [PLIST(@"") propertyListValue]) - - EXPECT_EXCEPTION( - @"-[propertyListValue] detecting invalid format #3", - OFInvalidFormatException, - [PLIST(@"") propertyListValue]) - - EXPECT_EXCEPTION( - @"-[propertyListValue] detecting invalid format #4", - OFInvalidFormatException, - [PLIST(@"") propertyListValue]) - - EXPECT_EXCEPTION( - @"-[propertyListValue] detecting invalid format #5", - OFInvalidFormatException, - [PLIST(@"") propertyListValue]) + objectByParsingPropertyList]) + + EXPECT_EXCEPTION( + @"-[objectByParsingPropertyList] detecting invalid format #1", + OFInvalidFormatException, + [PLIST(@"") objectByParsingPropertyList]) + + EXPECT_EXCEPTION( + @"-[objectByParsingPropertyList] detecting invalid format #2", + OFInvalidFormatException, + [PLIST(@"") objectByParsingPropertyList]) + + EXPECT_EXCEPTION( + @"-[objectByParsingPropertyList] detecting invalid format #3", + OFInvalidFormatException, + [PLIST(@"") objectByParsingPropertyList]) + + EXPECT_EXCEPTION( + @"-[objectByParsingPropertyList] detecting invalid format #4", + OFInvalidFormatException, + [PLIST(@"") + objectByParsingPropertyList]) + + EXPECT_EXCEPTION( + @"-[objectByParsingPropertyList] detecting invalid format #5", + OFInvalidFormatException, + [PLIST(@"") + objectByParsingPropertyList]) objc_autoreleasePoolPop(pool); } @end Index: tests/OFSCTPSocketTests.m ================================================================== --- tests/OFSCTPSocketTests.m +++ tests/OFSCTPSocketTests.m @@ -40,11 +40,11 @@ (port = [server bindToHost: @"127.0.0.1" port: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EPROTONOSUPPORT: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSCTPSocket] -[bindToHost:port:]: " @"SCTP unsupported, skipping tests"]; break; default: Index: tests/OFSPXSocketTests.m ================================================================== --- tests/OFSPXSocketTests.m +++ tests/OFSPXSocketTests.m @@ -90,23 +90,23 @@ TEST(@"-[bindToPort:]", R(address1 = [sockServer bindToPort: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXSocket] -[bindToPort:]: " @"IPX unsupported, skipping tests"]; break; case ESOCKTNOSUPPORT: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXSocket] -[bindToPort:]: " @"SPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXSocket] -[bindToPort:]: " @"IPX not configured, skipping tests"]; break; default: @@ -176,11 +176,11 @@ TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]", delegate->_accepted && delegate->_connected) } @catch (OFObserveFailedException *e) { switch (e.errNo) { case ENOTSOCK: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXSocket] -[asyncAccept] & " @"-[asyncConnectToNode:network:port:]: select() " @"not supported for SPX, skipping test"]; break; Index: tests/OFSPXStreamSocketTests.m ================================================================== --- tests/OFSPXStreamSocketTests.m +++ tests/OFSPXStreamSocketTests.m @@ -90,23 +90,23 @@ TEST(@"-[bindToPort:]", R(address1 = [sockServer bindToPort: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[bindToPort:]: " @"IPX unsupported, skipping tests"]; break; case ESOCKTNOSUPPORT: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[bindToPort:]: " @"SPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[bindToPort:]: " @"IPX not configured, skipping tests"]; break; default: @@ -180,11 +180,11 @@ TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]", delegate->_accepted && delegate->_connected) } @catch (OFObserveFailedException *e) { switch (e.errNo) { case ENOTSOCK: - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[asyncAccept] & " @"-[asyncConnectToNode:network:port:]: select() " @"not supported for SPX, skipping test"]; break; Index: tests/OFSetTests.m ================================================================== --- tests/OFSetTests.m +++ tests/OFSetTests.m @@ -276,14 +276,14 @@ TEST(@"Detection of mutation during Fast Enumeration", ok); TEST(@"-[valueForKey:]", [(set1 = [[setClass setWithObjects: @"a", @"ab", @"abc", @"b", nil] valueForKey: @"length"]) isEqual: [setClass setWithObjects: - [OFNumber numberWithSize: 1], [OFNumber numberWithSize: 2], - [OFNumber numberWithSize: 3], nil]] && + [OFNumber numberWithInt: 1], [OFNumber numberWithInt: 2], + [OFNumber numberWithInt: 3], nil]] && [[set1 valueForKey: @"@count"] isEqual: - [OFNumber numberWithSize: 3]]) + [OFNumber numberWithInt: 3]]) objc_autoreleasePoolPop(pool); } - (void)setTests Index: tests/OFStreamTests.m ================================================================== --- tests/OFStreamTests.m +++ tests/OFStreamTests.m @@ -74,11 +74,11 @@ cstr = [t allocMemoryWithSize: pageSize - 2]; memset(cstr, 'X', pageSize - 3); cstr[pageSize - 3] = '\0'; TEST(@"-[readLine]", [[t readLine] isEqual: @"foo"] && - (str = [t readLine]).length == pageSize - 3 && + [(str = [t readLine]) length] == pageSize - 3 && !strcmp(str.UTF8String, cstr)) objc_autoreleasePoolPop(pool); } @end Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -1067,28 +1067,33 @@ [C(@"c:\\..\\asd").stringByStandardizingPath isEqual: @"c:\\..\\asd"]) # endif #endif - TEST(@"-[decimalValue]", - C(@"1234").decimalValue == 1234 && - C(@"\r\n+123 ").decimalValue == 123 && - C(@"-500\t").decimalValue == -500 && - C(@"\t\t\r\n").decimalValue == 0) - - TEST(@"-[hexadecimalValue]", - C(@"123f").hexadecimalValue == 0x123f && - C(@"\t\n0xABcd\r").hexadecimalValue == 0xABCD && - C(@" xbCDE").hexadecimalValue == 0xBCDE && - C(@"$CdEf").hexadecimalValue == 0xCDEF && - C(@"\rFeh ").hexadecimalValue == 0xFE && - C(@"\r\t").hexadecimalValue == 0) - - TEST(@"-[octalValue]", - C(@"1234567").octalValue == 01234567 && - C(@"\r\n123").octalValue == 0123 && - C(@"765\t").octalValue == 0765 && C(@"\t\t\r\n").octalValue == 0) + TEST(@"-[longLongValue]", + C(@"1234").longLongValue == 1234 && + C(@"\r\n+123 ").longLongValue == 123 && + C(@"-500\t").longLongValue == -500 && + [C(@"-0x10\t") longLongValueWithBase: 0] == -0x10 && + C(@"\t\t\r\n").longLongValue == 0 && + [C(@"123f") longLongValueWithBase: 16] == 0x123f && + [C(@"\t\n0xABcd\r") longLongValueWithBase: 0] == 0xABCD && + [C(@"1234567") longLongValueWithBase: 8] == 01234567 && + [C(@"\r\n0123") longLongValueWithBase: 0] == 0123 && + [C(@"765\t") longLongValueWithBase: 8] == 0765 && + [C(@"\t\t\r\n") longLongValueWithBase: 8] == 0) + + TEST(@"-[unsignedLongLongValue]", + C(@"1234").unsignedLongLongValue == 1234 && + C(@"\r\n+123 ").unsignedLongLongValue == 123 && + C(@"\t\t\r\n").unsignedLongLongValue == 0 && + [C(@"123f") unsignedLongLongValueWithBase: 16] == 0x123f && + [C(@"\t\n0xABcd\r") unsignedLongLongValueWithBase: 0] == 0xABCD && + [C(@"1234567") unsignedLongLongValueWithBase: 8] == 01234567 && + [C(@"\r\n0123") unsignedLongLongValueWithBase: 0] == 0123 && + [C(@"765\t") unsignedLongLongValueWithBase: 8] == 0765 && + [C(@"\t\t\r\n") unsignedLongLongValueWithBase: 8] == 0) /* * These test numbers can be generated without rounding if we have IEEE * floating point numbers, thus we can use == on them. */ @@ -1107,11 +1112,11 @@ # if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K) # define INPUT @"\t-0.123456789 " # define EXPECTED -0.123456789 # else /* - * Solaris' strtod() has weird rounding on x86, but not on x86_64/ + * Solaris' strtod() has weird rounding on x86, but not on x86_64. * AmigaOS 3 with libnix has weird rounding as well. */ # define INPUT @"\t-0.125 " # define EXPECTED -0.125 # endif @@ -1122,25 +1127,21 @@ C(@"\r -INFINITY\n").doubleValue == -INFINITY && isnan(C(@" NAN\t\t").doubleValue)) #undef INPUT #undef EXPECTED - EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #1", - OFInvalidFormatException, [C(@"abc") decimalValue]) - EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #2", - OFInvalidFormatException, [C(@"0a") decimalValue]) - EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #3", - OFInvalidFormatException, [C(@"0 1") decimalValue]) - - EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #1", - OFInvalidFormatException, [C(@"0xABCDEFG") hexadecimalValue]) - EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #2", - OFInvalidFormatException, [C(@"0x") hexadecimalValue]) - EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #3", - OFInvalidFormatException, [C(@"$") hexadecimalValue]) - EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #4", - OFInvalidFormatException, [C(@"$ ") hexadecimalValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #1", + OFInvalidFormatException, [C(@"abc") longLongValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #2", + OFInvalidFormatException, [C(@"0a") longLongValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #3", + OFInvalidFormatException, [C(@"0 1") longLongValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #4", + OFInvalidFormatException, + [C(@"0xABCDEFG") longLongValueWithBase: 0]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #5", + OFInvalidFormatException, [C(@"0x") longLongValueWithBase: 0]) EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #1", OFInvalidFormatException, [C(@"0.0a") floatValue]) EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #2", OFInvalidFormatException, [C(@"0 0") floatValue]) @@ -1164,21 +1165,21 @@ */ EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #3", OFInvalidFormatException, [C(@"0,0") doubleValue]) #endif - EXPECT_EXCEPTION(@"Detect out of range in -[decimalValue]", + EXPECT_EXCEPTION(@"Detect out of range in -[longLongValue]", OFOutOfRangeException, - [C(@"12345678901234567890123456789012345678901234567890" + [C(@"-12345678901234567890123456789012345678901234567890" @"12345678901234567890123456789012345678901234567890") - decimalValue]) + longLongValueWithBase: 16]) - EXPECT_EXCEPTION(@"Detect out of range in -[hexadecimalValue]", + EXPECT_EXCEPTION(@"Detect out of range in -[unsignedLongLongValue]", OFOutOfRangeException, [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF") - hexadecimalValue]) + unsignedLongLongValueWithBase: 16]) TEST(@"-[characters]", (ua = C(@"fööbär🀺").characters) && !memcmp(ua, ucstr + 1, sizeof(ucstr) - 8)) #ifdef OF_BIG_ENDIAN Index: tests/OFSystemInfoTests.m ================================================================== --- tests/OFSystemInfoTests.m +++ tests/OFSystemInfoTests.m @@ -25,11 +25,11 @@ void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_FILES OFString *userConfigPath, *userDataPath; #endif - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout writeFormat: @"[OFSystemInfo] Page size: %zd\n", [OFSystemInfo pageSize]]; [of_stdout writeFormat: @"[OFSystemInfo] Number of CPUs: %zd\n", Index: tests/OFURLTests.m ================================================================== --- tests/OFURLTests.m +++ tests/OFURLTests.m @@ -19,11 +19,11 @@ #import "TestsAppDelegate.h" static OFString *module = @"OFURL"; static OFString *url_str = @"ht%3atp://us%3Aer:p%40w@ho%3Ast:1234/" - @"pa%3Fth?que%23ry#frag%23ment"; + @"pa%3Fth?que%23ry=1&f%26oo=b%3dar#frag%23ment"; @implementation TestsAppDelegate (OFURLTests) - (void)URLTests { void *pool = objc_autoreleasePoolPush(); @@ -154,13 +154,12 @@ TEST(@"-[password]", [u1.password isEqual: @"p@w"] && u4.password == nil) TEST(@"-[host]", [u1.host isEqual: @"ho:st"] && [u6.host isEqual: @"12:34::56:abcd"] && [u7.host isEqual: @"12:34::56:abcd"]) - TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]] && - [u4 port] == nil && - [u7.port isEqual: [OFNumber numberWithUInt16: 234]]) + TEST(@"-[port]", u1.port.unsignedShortValue == 1234 && + [u4 port] == nil && u7.port.unsignedShortValue == 234) TEST(@"-[path]", [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"]) TEST(@"-[pathComponents]", [u1.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"pa?th", nil]] && @@ -177,11 +176,15 @@ lastPathComponent] isEqual: @"foo"] && [[[OFURL URLWithString: @"http://host/"] lastPathComponent] isEqual: @"/"] && [u5.lastPathComponent isEqual: @"foo/bar"]) TEST(@"-[query]", - [u1.query isEqual: @"que#ry"] && u4.query == nil) + [u1.query isEqual: @"que#ry=1&f&oo=b=ar"] && u4.query == nil) + TEST(@"-[queryDictionary]", + [u1.queryDictionary isEqual: + [OFDictionary dictionaryWithKeysAndObjects: + @"que#ry", @"1", @"f&oo", @"b=ar", nil]]); TEST(@"-[fragment]", [u1.fragment isEqual: @"frag#ment"] && u4.fragment == nil) TEST(@"-[copy]", R(u4 = [[u1 copy] autorelease])) @@ -268,10 +271,16 @@ EXPECT_EXCEPTION( @"-[setURLEncodedQuery:] with invalid characters fails", OFInvalidFormatException, mu.URLEncodedQuery = @"`") + TEST(@"-[setQueryDictionary:]", + (mu.queryDictionary = [OFDictionary dictionaryWithKeysAndObjects: + @"foo&bar", @"baz=qux", @"f=oobar", @"b&azqux", nil]) && + [mu.URLEncodedQuery isEqual: + @"foo%26bar=baz%3Dqux&f%3Doobar=b%26azqux"]) + TEST(@"-[setFragment:]", (mu.fragment = @"frag/ment?#") && [mu.URLEncodedFragment isEqual: @"frag/ment?%23"]) TEST(@"-[setURLEncodedFragment:]", Index: tests/OFValueTests.m ================================================================== --- tests/OFValueTests.m +++ tests/OFValueTests.m @@ -26,13 +26,14 @@ @implementation TestsAppDelegate (OFValueTests) - (void)valueTests { void *pool = objc_autoreleasePoolPush(); of_range_t range = of_range(1, 64), range2; - of_point_t point = of_point(1.5, 3), point2; - of_dimension_t dimension = of_dimension(4.5, 5), dimension2; - of_rectangle_t rectangle = of_rectangle(1.5, 3, 4.5, 6), rectangle2; + of_point_t point = of_point(1.5f, 3.0f), point2; + of_dimension_t dimension = of_dimension(4.5f, 5.0f), dimension2; + of_rectangle_t rectangle = of_rectangle(1.5f, 3.0f, 4.5f, 6.0f); + of_rectangle_t rectangle2; OFValue *value; void *pointer = &value; TEST(@"+[valueWithBytes:objCType:]", (value = [OFValue valueWithBytes: &range Index: tests/RuntimeTests.m ================================================================== --- tests/RuntimeTests.m +++ tests/RuntimeTests.m @@ -65,10 +65,15 @@ - (void)runtimeTests { void *pool = objc_autoreleasePoolPush(); RuntimeTest *rt = [[[RuntimeTest alloc] init] autorelease]; OFString *t, *foo; +#ifdef OF_OBJFW_RUNTIME + int cid1, cid2; + uintmax_t value; + id object; +#endif EXPECT_EXCEPTION(@"Calling a non-existent method via super", OFNotImplementedException, [rt superTest]) TEST(@"Calling a method via a super with self == nil", @@ -81,9 +86,28 @@ TEST(@"copy, nonatomic properties", [rt.foo isEqual: foo] && rt.foo != foo && rt.foo.retainCount == 1) rt.bar = t; TEST(@"retain, atomic properties", rt.bar == t && t.retainCount == 3) + +#ifdef OF_OBJFW_RUNTIME + if (sizeof(uintptr_t) == 8) + value = 0xDEADBEEFDEADBEF; + else if (sizeof(uintptr_t) == 4) + value = 0xDEADBEF; + else + abort(); + + TEST(@"Tagged pointers", + (cid1 = objc_registerTaggedPointerClass([OFString class])) != -1 && + (cid2 = objc_registerTaggedPointerClass([OFNumber class])) != -1 && + (object = objc_createTaggedPointer(cid2, (uintptr_t)value)) && + object_getClass(object) == [OFNumber class] && + [object class] == [OFNumber class] && + object_getTaggedPointerValue(object) == value && + objc_createTaggedPointer(cid2, UINTPTR_MAX >> 4) != nil && + objc_createTaggedPointer(cid2, (UINTPTR_MAX >> 4) + 1) == nil) +#endif objc_autoreleasePoolPop(pool); } @end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -68,12 +68,12 @@ inModule: (OFString *)module; - (void)outputFailure: (OFString *)test inModule: (OFString *)module; @end -@interface TestsAppDelegate (OFASN1DERValueTests) -- (void)ASN1DERValueTests; +@interface TestsAppDelegate (OFASN1DERParsingTests) +- (void)ASN1DERParsingTests; @end @interface TestsAppDelegate (OFASN1DERRepresentationTests) - (void)ASN1DERRepresentationTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -148,11 +148,11 @@ @"\nRuntime error: Unhandled exception:\n%@\n", e]; OFString *backtrace = [OFString stringWithFormat: @"\nBacktrace:\n %@\n\n", [[e backtrace] componentsJoinedByString: @"\n "]]; - of_stdout.foregroundColor = [OFColor red]; + [of_stdout setForegroundColor: [OFColor red]]; [of_stdout writeString: string]; [of_stdout writeString: backtrace]; # if defined(OF_WII) [of_stdout reset]; @@ -203,21 +203,21 @@ @implementation TestsAppDelegate - (void)outputTesting: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { - of_stdout.foregroundColor = [OFColor yellow]; + [of_stdout setForegroundColor: [OFColor yellow]]; [of_stdout writeFormat: @"[%@] %@: testing...", module, test]; } else [of_stdout writeFormat: @"[%@] %@: ", module, test]; } - (void)outputSuccess: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { - of_stdout.foregroundColor = [OFColor lime]; + [of_stdout setForegroundColor: [OFColor lime]]; [of_stdout eraseLine]; [of_stdout writeFormat: @"\r[%@] %@: ok\n", module, test]; } else [of_stdout writeLine: @"ok"]; } @@ -224,11 +224,11 @@ - (void)outputFailure: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { - of_stdout.foregroundColor = [OFColor red]; + [of_stdout setForegroundColor: [OFColor red]]; [of_stdout eraseLine]; [of_stdout writeFormat: @"\r[%@] %@: failed\n", module, test]; #ifdef OF_WII [of_stdout reset]; @@ -378,11 +378,11 @@ #ifdef OF_HAVE_FILES [self serializationTests]; #endif [self JSONTests]; [self propertyListTests]; - [self ASN1DERValueTests]; + [self ASN1DERParsingTests]; [self ASN1DERRepresentationTests]; #if defined(OF_HAVE_PLUGINS) [self pluginTests]; #endif #ifdef OF_WINDOWS Index: tests/iOS.xcodeproj/project.pbxproj ================================================================== --- tests/iOS.xcodeproj/project.pbxproj +++ tests/iOS.xcodeproj/project.pbxproj @@ -304,11 +304,11 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", ); OTHER_LDFLAGS = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = zone.heap.objfw.tests; + PRODUCT_BUNDLE_IDENTIFIER = im.nil.objfw.tests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -324,11 +324,11 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", ); OTHER_LDFLAGS = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = zone.heap.objfw.tests; + PRODUCT_BUNDLE_IDENTIFIER = im.nil.objfw.tests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; Index: tests/plugin/Info.plist.in ================================================================== --- tests/plugin/Info.plist.in +++ tests/plugin/Info.plist.in @@ -5,11 +5,11 @@ CFBundleExecutable TestPlugin CFBundleName TestPlugin CFBundleIdentifier - zone.heap.objfw.testplugin + im.nil.objfw.tests.plugin CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BNDL CFBundleVersion Index: tests/serialization.xml ================================================================== --- tests/serialization.xml +++ tests/serialization.xml @@ -16,11 +16,11 @@ Qu"xbar test 1234 - 40934a456d5cfaad + 40934a456d5cfaad asd 40934a456d5cfaad Index: tests/terminal/TerminalTests.m ================================================================== --- tests/terminal/TerminalTests.m +++ tests/terminal/TerminalTests.m @@ -42,61 +42,61 @@ [of_stdout writeFormat: @"%dx%d\n", of_stdout.columns, of_stdout.rows]; i = 0; for (OFColor *color in colors) { - of_stdout.foregroundColor = color; + [of_stdout setForegroundColor: color]; [of_stdout writeFormat: @"%zx", i++]; } [of_stdout reset]; [of_stdout writeLine: @"R"]; i = 0; for (OFColor *color in colors) { - of_stdout.backgroundColor = color; + [of_stdout setBackgroundColor: color]; [of_stdout writeFormat: @"%zx", i++]; } [of_stdout reset]; [of_stdout writeLine: @"R"]; i = 0; reverseEnumerator = [colors.reversedArray objectEnumerator]; for (OFColor *color in colors) { - of_stdout.foregroundColor = color; - of_stdout.backgroundColor = [reverseEnumerator nextObject]; + [of_stdout setForegroundColor: color]; + [of_stdout setBackgroundColor: [reverseEnumerator nextObject]]; [of_stdout writeFormat: @"%zx", i++]; } [of_stdout reset]; [of_stdout writeLine: @"R"]; for (i = 0; i < colors.count * 2; i++) { if (i % 2) - of_stdout.backgroundColor = [colors objectAtIndex: - ((i / 2) + 2) % colors.count]; + [of_stdout setBackgroundColor: [colors objectAtIndex: + ((i / 2) + 2) % colors.count]]; else - of_stdout.foregroundColor = - [colors objectAtIndex: i / 2]; + [of_stdout setForegroundColor: + [colors objectAtIndex: i / 2]]; [of_stdout writeFormat: @"%zx", i / 2]; } [of_stdout reset]; [of_stdout writeLine: @"R"]; [of_stdout writeLine: @"Press return"]; [of_stdin readLine]; - of_stdout.backgroundColor = [OFColor green]; + [of_stdout setBackgroundColor: [OFColor green]]; [of_stdout writeString: @"Hello!"]; [OFThread sleepForTimeInterval: 2]; [of_stdout eraseLine]; [of_stdout writeString: @"World!"]; [OFThread sleepForTimeInterval: 2]; [of_stdout clear]; [OFThread sleepForTimeInterval: 2]; - of_stdout.cursorPosition = of_point(5, 3); + [of_stdout setCursorPosition: of_point(5, 3)]; [of_stdout writeString: @"Text at (5, 3)"]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(-2, 0)]; [OFThread sleepForTimeInterval: 2]; @@ -109,13 +109,13 @@ [of_stdout setRelativeCursorPosition: of_point(1, 1)]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(-1, -1)]; [OFThread sleepForTimeInterval: 2]; - of_stdout.cursorColumn = 2; + [of_stdout setCursorColumn: 2]; [OFThread sleepForTimeInterval: 2]; [of_stdout reset]; [OFApplication terminate]; } @end Index: utils/ofarc/LHAArchive.m ================================================================== --- utils/ofarc/LHAArchive.m +++ utils/ofarc/LHAArchive.m @@ -44,10 +44,13 @@ #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS OFNumber *mode = entry.mode; if (mode == nil) return; + + mode = [OFNumber numberWithUnsignedShort: + mode.unsignedShortValue & 0777]; of_file_attributes_t attributes = [OFDictionary dictionaryWithObject: mode forKey: of_file_attribute_key_posix_permissions]; @@ -143,28 +146,28 @@ @"%04" PRIX16, entry.CRC16]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compressed_size", - [@"[" - @" 'Compressed: '," - @" [" - @" {'size == 1': '1 byte'}," - @" {'': '%[size] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" 'Compressed: '," + @" [" + @" {'size == 1': '1 byte'}," + @" {'': '%[size] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"size", compressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_uncompressed_size", - [@"[" - @" 'Uncompressed: '," - @" [" - @" {'size == 1': '1 byte'}," - @" {'': '%[size] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" 'Uncompressed: '," + @" [" + @" {'size == 1': '1 byte'}," + @" {'': '%[size] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"size", uncompressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compression_method", @"Compression method: %[method]", @@ -179,11 +182,11 @@ @"date", date)]; if (entry.mode != nil) { OFString *modeString = [OFString stringWithFormat: - @"%" PRIo16, entry.mode.uInt16Value]; + @"%ho", entry.mode.unsignedShortValue]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED(@"list_mode", @"Mode: %[mode]", @"mode", modeString)]; @@ -467,20 +470,20 @@ attributes = [fileManager attributesOfItemAtPath: fileName]; type = attributes.fileType; entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName]; #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS - entry.mode = [OFNumber numberWithUInt16: + entry.mode = [OFNumber numberWithUnsignedLong: attributes.filePOSIXPermissions]; #endif entry.date = attributes.fileModificationDate; #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER entry.UID = - [OFNumber numberWithUInt16: attributes.filePOSIXUID]; + [OFNumber numberWithUnsignedLong: attributes.filePOSIXUID]; entry.GID = - [OFNumber numberWithUInt16: attributes.filePOSIXGID]; + [OFNumber numberWithUnsignedLong: attributes.filePOSIXGID]; entry.owner = attributes.fileOwner; entry.group = attributes.fileGroup; #endif if ([type isEqual: of_file_type_directory]) @@ -487,11 +490,12 @@ entry.compressionMethod = @"-lhd-"; output = [_archive streamForWritingEntry: entry]; if ([type isEqual: of_file_type_regular]) { - uintmax_t written = 0, size = attributes.fileSize; + unsigned long long written = 0; + unsigned long long size = attributes.fileSize; int8_t percent = -1, newPercent; OFFile *input = [OFFile fileWithPath: fileName mode: @"r"]; Index: utils/ofarc/TarArchive.m ================================================================== --- utils/ofarc/TarArchive.m +++ utils/ofarc/TarArchive.m @@ -33,12 +33,13 @@ static void setPermissions(OFString *path, OFTarArchiveEntry *entry) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS + OFNumber *mode = [OFNumber numberWithUnsignedShort: entry.mode & 0777]; of_file_attributes_t attributes = [OFDictionary - dictionaryWithObject: [OFNumber numberWithUInt16: entry.mode] + dictionaryWithObject: mode forKey: of_file_attribute_key_posix_permissions]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; #endif @@ -124,17 +125,17 @@ OFString *GID = [OFString stringWithFormat: @"%u", entry.GID]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED(@"list_size", - [@"[" - @" 'Size: '," - @" [" - @" {'size == 1': '1 byte'}," - @" {'': '%[size] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" 'Size: '," + @" [" + @" {'size == 1': '1 byte'}," + @" {'': '%[size] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"size", size)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED(@"list_mode", @"Mode: %[mode]", @"mode", mode)]; Index: utils/ofarc/ZIPArchive.m ================================================================== --- utils/ofarc/ZIPArchive.m +++ utils/ofarc/ZIPArchive.m @@ -42,15 +42,16 @@ setPermissions(OFString *path, OFZIPArchiveEntry *entry) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS if ((entry.versionMadeBy >> 8) == OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) { - uint16_t mode = entry.versionSpecificAttributes >> 16; + OFNumber *mode = [OFNumber numberWithUnsignedShort: + (entry.versionSpecificAttributes >> 16) & 0777]; of_file_attribute_key_t key = of_file_attribute_key_posix_permissions; of_file_attributes_t attributes = [OFDictionary - dictionaryWithObject: [OFNumber numberWithUInt16: mode] + dictionaryWithObject: mode forKey: key]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; } @@ -136,28 +137,28 @@ localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compressed_size", - [@"[" - @" 'Compressed: '," - @" [" - @" {'size == 1': '1 byte'}," - @" {'': '%[size] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" 'Compressed: '," + @" [" + @" {'size == 1': '1 byte'}," + @" {'': '%[size] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"size", compressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_uncompressed_size", - [@"[" - @" 'Uncompressed: '," - @" [" - @" {'size == 1': '1 byte'}," - @" {'': '%[size] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" 'Uncompressed: '," + @" [" + @" {'size == 1': '1 byte'}," + @" {'': '%[size] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"size", uncompressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compression_method", @"Compression method: %[method]", @@ -419,11 +420,11 @@ OFArray OF_GENERIC (OFString *) *components; OFString *fileName; of_file_attributes_t attributes; bool isDirectory = false; OFMutableZIPArchiveEntry *entry; - uintmax_t size; + unsigned long long size; OFStream *output; components = localFileName.pathComponents; fileName = [components componentsJoinedByString: @"/"]; @@ -456,11 +457,11 @@ [entry makeImmutable]; output = [_archive streamForWritingEntry: entry]; if (!isDirectory) { - uintmax_t written = 0; + unsigned long long written = 0; int8_t percent = -1, newPercent; OFFile *input = [OFFile fileWithPath: fileName mode: @"r"]; Index: utils/ofhttp/OFHTTP.m ================================================================== --- utils/ofhttp/OFHTTP.m +++ utils/ofhttp/OFHTTP.m @@ -26,10 +26,13 @@ #import "OFHTTPClient.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFLocale.h" #import "OFOptionsParser.h" +#ifdef OF_HAVE_PLUGINS +# import "OFPlugin.h" +#endif #import "OFSandbox.h" #import "OFStdIOStream.h" #import "OFSystemInfo.h" #import "OFTCPSocket.h" #import "OFTLSSocket.h" @@ -67,11 +70,11 @@ of_http_request_method_t _method; OFMutableDictionary *_clientHeaders; OFHTTPClient *_HTTPClient; char *_buffer; OFStream *_output; - intmax_t _received, _length, _resumedFrom; + unsigned long long _received, _length, _resumedFrom; ProgressBar *_progressBar; } - (void)downloadNextURL; @end @@ -272,10 +275,21 @@ objc_autoreleasePoolPop(pool); return [fileName autorelease]; } @implementation OFHTTP +#ifdef OF_HAVE_PLUGINS ++ (void)initialize +{ + if (self != [OFHTTP class]) + return; + + /* Opportunistically try loading ObjOpenSSL and ignore any errors. */ + of_dlopen(@"objopenssl", OF_RTLD_LAZY); +} +#endif + - (instancetype)init { self = [super init]; @try { @@ -332,11 +346,12 @@ else { _body = [[OFFile alloc] initWithPath: path mode: @"r"]; @try { - uintmax_t fileSize = [[OFFileManager defaultManager] + unsigned long long fileSize = + [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; contentLength = [OFString stringWithFormat: @"%ju", fileSize]; [_clientHeaders setObject: contentLength @@ -374,18 +389,18 @@ @try { size_t pos = [proxy rangeOfString: @":" options: OF_STRING_SEARCH_BACKWARDS].location; OFString *host; - intmax_t port; + 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)].decimalValue; + port = [proxy substringWithRange: of_range(pos + 1, + proxy.length - pos - 1)].unsignedLongLongValue; if (port > UINT16_MAX) @throw [OFOutOfRangeException exception]; [OFTCPSocket setSOCKS5Host: host]; @@ -443,23 +458,23 @@ optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 'b': - self.body = optionsParser.argument; + [self setBody: optionsParser.argument]; break; case 'h': help(of_stdout, true, 0); break; case 'H': [self addHeader: optionsParser.argument]; break; case 'm': - self.method = optionsParser.argument; + [self setMethod: optionsParser.argument]; break; case 'P': - self.proxy = optionsParser.argument; + [self setProxy: optionsParser.argument]; break; case ':': if (optionsParser.lastLongOption != nil) [of_stderr writeLine: OF_LOCALIZED(@"long_argument_missing", @@ -719,12 +734,15 @@ [_progressBar stop]; [_progressBar draw]; [_progressBar release]; _progressBar = nil; - if (!_quiet) - [of_stdout writeString: @"\n Error!\n"]; + if (!_quiet) { + [of_stdout writeString: @"\n "]; + [of_stdout writeLine: OF_LOCALIZED(@"download_error", + @"Error!")]; + } URL = [_URLs objectAtIndex: _URLIndex - 1]; [of_stderr writeLine: OF_LOCALIZED( @"download_failed_exception", @"%[prog]: Failed to download <%[url]>!\n" @@ -742,11 +760,11 @@ _received += length; [_output writeBuffer: buffer length: length]; - _progressBar.received = _received; + [_progressBar setReceived: _received]; if (response.atEndOfStream) { [_progressBar stop]; [_progressBar draw]; [_progressBar release]; @@ -783,11 +801,11 @@ if (type == nil) type = OF_LOCALIZED(@"type_unknown", @"unknown"); if (lengthString != nil) { - _length = lengthString.decimalValue; + _length = lengthString.unsignedLongLongValue; if (_resumedFrom + _length >= GIBIBYTE) { lengthString = [OFString stringWithFormat: @"%,.2f", (float)(_resumedFrom + _length) / GIBIBYTE]; @@ -810,16 +828,16 @@ @"num", lengthString); } else { lengthString = [OFString stringWithFormat: @"%jd", _resumedFrom + _length]; lengthString = OF_LOCALIZED(@"size_bytes", - [@"[" - @" [" - @" {'num == 1': '1 byte'}," - @" {'': '%[num] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" [" + @" {'num == 1': '1 byte'}," + @" {'': '%[num] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"num", lengthString); } } else lengthString = OF_LOCALIZED(@"size_unknown", @"unknown"); @@ -920,11 +938,11 @@ if (!_quiet) { _progressBar = [[ProgressBar alloc] initWithLength: _length resumedFrom: _resumedFrom]; - _progressBar.received = _received; + [_progressBar setReceived: _received]; [_progressBar draw]; } [_currentFileName release]; _currentFileName = nil; @@ -1008,18 +1026,19 @@ if (_currentFileName == nil) _currentFileName = [URL.path.lastPathComponent copy]; if (_continue) { @try { - uintmax_t size = [[OFFileManager defaultManager] + unsigned long long size = + [[OFFileManager defaultManager] attributesOfItemAtPath: _currentFileName].fileSize; OFString *range; - if (size > INTMAX_MAX) + if (size > ULLONG_MAX) @throw [OFOutOfRangeException exception]; - _resumedFrom = (intmax_t)size; + _resumedFrom = (unsigned long long)size; range = [OFString stringWithFormat: @"bytes=%jd-", _resumedFrom]; [clientHeaders setObject: range forKey: @"Range"]; Index: utils/ofhttp/ProgressBar.h ================================================================== --- utils/ofhttp/ProgressBar.h +++ utils/ofhttp/ProgressBar.h @@ -17,23 +17,27 @@ #import "OFObject.h" @class OFDate; @class OFTimer; + +#define BPS_WINDOW_SIZE 10 @interface ProgressBar: OFObject { - intmax_t _received, _lastReceived, _length, _resumedFrom; + unsigned long long _received, _lastReceived, _length, _resumedFrom; OFDate *_startDate, *_lastReceivedDate; OFTimer *_drawTimer, *_BPSTimer; bool _stopped; float _BPS; double _ETA; + float _BPSWindow[BPS_WINDOW_SIZE]; + size_t _BPSWindowIndex, _BPSWindowLength; } -- (instancetype)initWithLength: (intmax_t)length - resumedFrom: (intmax_t)resumedFrom; -- (void)setReceived: (intmax_t)received; +- (instancetype)initWithLength: (unsigned long long)length + resumedFrom: (unsigned long long)resumedFrom; +- (void)setReceived: (unsigned long long)received; - (void)draw; - (void)calculateBPSAndETA; - (void)stop; @end Index: utils/ofhttp/ProgressBar.m ================================================================== --- utils/ofhttp/ProgressBar.m +++ utils/ofhttp/ProgressBar.m @@ -31,12 +31,12 @@ #define KIBIBYTE (1024) #define UPDATE_INTERVAL 0.1 @implementation ProgressBar -- (instancetype)initWithLength: (intmax_t)length - resumedFrom: (intmax_t)resumedFrom +- (instancetype)initWithLength: (unsigned long long)length + resumedFrom: (unsigned long long)resumedFrom { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -76,11 +76,11 @@ [_BPSTimer release]; [super dealloc]; } -- (void)setReceived: (intmax_t)received +- (void)setReceived: (unsigned long long)received { _received = received; } - (void)_drawProgress @@ -202,16 +202,16 @@ @"num", num)]; } else { OFString *num = [OFString stringWithFormat: @"%jd", _resumedFrom + _received]; [of_stdout writeString: OF_LOCALIZED(@"progress_bytes", - [@"[" - @" [" - @" {'num == 1': '1 byte '}," - @" {'': '%[num] bytes'}" - @" ]" - @"]" JSONValue], + @"[" + @" [" + @" {'num == 1': '1 byte '}," + @" {'': '%[num] bytes'}" + @" ]" + @"]".objectByParsingJSON, @"num", num)]; } [of_stdout writeString: @" "]; @@ -254,12 +254,22 @@ [self _drawReceived]; } - (void)calculateBPSAndETA { - _BPS = (float)(_received - _lastReceived) / + _BPSWindow[_BPSWindowIndex++ % BPS_WINDOW_SIZE] = + (float)(_received - _lastReceived) / -(float)_lastReceivedDate.timeIntervalSinceNow; + + if (_BPSWindowLength < BPS_WINDOW_SIZE) + _BPSWindowLength++; + + _BPS = 0; + for (size_t i = 0; i < _BPSWindowLength; i++) + _BPS += _BPSWindow[i]; + _BPS /= _BPSWindowLength; + _ETA = (double)(_length - _received) / _BPS; _lastReceived = _received; [_lastReceivedDate release]; _lastReceivedDate = [[OFDate alloc] init]; Index: utils/ofhttp/lang/de.json ================================================================== --- utils/ofhttp/lang/de.json +++ utils/ofhttp/lang/de.json @@ -66,10 +66,11 @@ ], "download_failed": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " HTTP Status-Code: %[code]" ], + "download_error": "Fehler!", "download_failed_exception": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " %[exception]" ], "download_done": "Fertig!", Index: utils/ofsock/OFSock.m ================================================================== --- utils/ofsock/OFSock.m +++ utils/ofsock/OFSock.m @@ -60,11 +60,11 @@ [of_stderr writeLine: @"Need a port!"]; [OFApplication terminateWithStatus: 1]; } [sock connectToHost: URL.host - port: URL.port.uInt16Value]; + port: URL.port.shortValue]; return [OFPair pairWithFirstObject: sock secondObject: sock]; }