Comment: | Merge trunk into 1.0 branch |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | 1.0 |
Files: | files | file ages | folders |
SHA3-256: |
370ec3dc84fc8fffcf0c8daf7d90e0dc |
User & Date: | js on 2020-05-28 23:31:27 |
Other Links: | branch diff | manifest | tags |
2020-05-28
| ||
23:45 | Remove utils/ofsock, as it is not ready for 1.0 check-in: cc7caa19be user: js tags: 1.0 | |
23:31 | Merge trunk into 1.0 branch check-in: 370ec3dc84 user: js tags: 1.0 | |
23:22 | OFIPXSocket: Minor documentation fix check-in: 2d409b0c35 user: js tags: trunk | |
2020-03-02
| ||
20:24 | Merge branch 'master' into 1.0 check-in: e3bbb35784 user: js tags: 1.0 | |
Added .fossil-settings/clean-glob version [02ac598dea].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.so *.so.* */.deps .deps aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure DerivedData docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/objc_sync/objc_sync tests/plugin/Info.plist tests/terminal/terminal_tests tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp utils/ofsock/ofsock |
Added .fossil-settings/ignore-glob version [fea53f5b92].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.orig *.so *.so.* */.deps .deps .git aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure DerivedData docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser tests/iOS.xcodeproj/project.xcworkspace tests/iOS.xcodeproj/xcuserdata tests/objc_sync/objc_sync tests/plugin/Info.plist tests/terminal/terminal_tests tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp utils/ofsock/ofsock |
Added .fossil-settings/keep-glob version [421e4b3d79].
> | 1 | .git |
Modified .gitignore from [dbd7d8e2dc] to [79c7b883a0].
1 2 3 4 5 6 7 8 9 10 | *.a *.bundle *.dep *.dll *.dylib *.library *.o *.orig *.so *.so.* | > > > < > > < < < < < < > < < < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.orig *.so *.so.* .deps .fslckout _FOSSIL_ aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure DerivedData docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser tests/iOS.xcodeproj/project.xcworkspace tests/iOS.xcodeproj/xcuserdata tests/objc_sync/objc_sync tests/plugin/Info.plist tests/terminal/terminal_tests tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp utils/ofsock/ofsock |
Modified .travis.yml from [a4ba9a887a] to [53acd6323f].
1 2 3 4 5 6 7 | language: c matrix: include: # Linux - os: linux compiler: gcc | > > > > > | > > | > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | language: c matrix: include: # Linux - os: linux compiler: clang dist: precise sudo: required - os: linux compiler: gcc dist: precise sudo: required - os: linux arch: arm64 compiler: clang dist: precise sudo: required - os: linux arch: arm64 compiler: gcc dist: precise sudo: required - os: linux arch: ppc64le compiler: clang dist: precise sudo: required - os: linux arch: ppc64le compiler: gcc dist: precise sudo: required # Clang seems to have broken exceptions on s390x #- os: linux # arch: s390x # compiler: clang # dist: precise # sudo: required - os: linux arch: s390x compiler: gcc dist: precise sudo: required - os: linux compiler: clang dist: trusty sudo: required - os: linux compiler: gcc dist: trusty sudo: required - os: linux compiler: clang dist: xenial sudo: required - os: linux compiler: gcc dist: xenial sudo: required - os: linux compiler: clang dist: bionic sudo: required - os: linux compiler: gcc dist: bionic sudo: required # macOS - os: osx osx_image: xcode11.2 language: objective-c env: |
︙ | ︙ | |||
187 188 189 190 191 192 193 | - os: linux dist: trusty env: - config=wii before_install: - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then | | > > > > > > > | > | > > > | < > > > > | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | - os: linux dist: trusty env: - config=wii before_install: - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then case "$TRAVIS_CPU_ARCH" in amd64 | s390x) pkgs="gobjc-multilib"; ;; *) pkgs="gobjc"; ;; esac; pkgs="$pkgs libsctp-dev"; if grep precise /etc/lsb-release >/dev/null; then pkgs="$pkgs ipx"; fi; if ! sudo apt-get -qq install -y $pkgs >/tmp/apt_log 2>&1; then cat /tmp/apt_log; exit 1; fi; if grep precise /etc/lsb-release >/dev/null; then sudo ipx_internal_net add 1234 123456; fi; fi - if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" -o "$config" = "wii" ]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb; sudo dpkg -i devkitpro-pacman.deb; |
︙ | ︙ | |||
222 223 224 225 226 227 228 | - if [ "$config" = "amigaos" ]; then wget -q https://franke.ms/download/amiga-gcc.tgz; tar -C / -xzf amiga-gcc.tgz; fi script: | > > > | > > > | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | - if [ "$config" = "amigaos" ]; then wget -q https://franke.ms/download/amiga-gcc.tgz; tar -C / -xzf amiga-gcc.tgz; fi script: # This needs to use ed on macOS, as it has no GNU sed, and sed on Linux, as # some Travis hosts have no ed. - if [ "$TRAVIS_OS_NAME" = "osx" ]; then echo -e '%s/-DSTDOUT$/&_SIMPLE/\nwq' | ed -s tests/Makefile; else sed -i 's/-DSTDOUT$/&_SIMPLE/' tests/Makefile; fi - build() { if ! git clean -fxd >/tmp/clean_log 2>&1; then cat /tmp/clean_log; exit 1; fi; echo ">> Configuring with $@"; |
︙ | ︙ | |||
250 251 252 253 254 255 256 | exit 1; fi; } - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then build_32_64() { build OBJC="$CC" $@; | > > > | > > > > > > > > > > > | | | | > | | | | | < | > | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | exit 1; fi; } - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then build_32_64() { build OBJC="$CC" $@; case "$TRAVIS_CPU_ARCH" in amd64) build OBJC="$CC -m32" --host=i686-pc-linux-gnu $@; ;; s390x) build OBJC="$CC -m31" --host=s390-pc-linux-gnu $@; ;; esac }; build_32_64; build_32_64 --enable-seluid24; build_32_64 --disable-compiler-tls; true The following are not CPU-dependent, so only run them on amd64; if [ "$TRAVIS_CPU_ARCH" = "amd64" ]; then build_32_64 --disable-threads; build_32_64 --disable-threads --disable-sockets; build_32_64 --disable-threads --disable-files; build_32_64 --disable-threads --disable-sockets --disable-files; build_32_64 --disable-sockets; build_32_64 --disable-sockets --disable-files; build_32_64 --disable-files; build_32_64 --disable-shared; build_32_64 --disable-shared --enable-seluid24; build_32_64 --disable-compiler-tls --disable-threads; fi; fi - if [ "$TRAVIS_OS_NAME" = "osx" -a -z "$config" ]; then build_mac_32_64() { build $@; if [ -z "$no32bit" ]; then build OBJC="clang -m32" --host=i386-apple-darwin $@; |
︙ | ︙ |
Modified Makefile from [8220802d40] to [c0716d54d0].
︙ | ︙ | |||
14 15 16 17 18 19 20 | utils tests: src tarball: echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz | | < < | > | > | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | utils tests: src tarball: 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' | \ 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} gzip -9 objfw-${PACKAGE_VERSION}.tar rm -f objfw-${PACKAGE_VERSION}.tar gpg -b objfw-${PACKAGE_VERSION}.tar.gz || true echo "Generating documentation..." rm -fr docs doxygen >/dev/null rm -fr objfw-docs-${PACKAGE_VERSION} objfw-docs-${PACKAGE_VERSION}.tar \ objfw-docs-${PACKAGE_VERSION}.tar.gz mv docs objfw-docs-${PACKAGE_VERSION} echo "Generating docs tarball for version ${PACKAGE_VERSION}..." ofarc -cq objfw-docs-${PACKAGE_VERSION}.tar \ $$(find objfw-docs-${PACKAGE_VERSION} | sort) rm -fr objfw-docs-${PACKAGE_VERSION} gzip -9 objfw-docs-${PACKAGE_VERSION}.tar rm -f objfw-docs-${PACKAGE_VERSION}.tar gpg -b objfw-docs-${PACKAGE_VERSION}.tar.gz || true |
Modified PLATFORMS.md from [d342907c41] to [98e6767a77].
︙ | ︙ | |||
76 77 78 79 80 81 82 | * Runtimes: Apple Linux ----- * Architectures: Alpha, ARMv6, ARM64, Itanium, m68k, MIPS (O32), RISC-V 64, | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | * Runtimes: Apple Linux ----- * Architectures: Alpha, ARMv6, ARM64, Itanium, m68k, MIPS (O32), RISC-V 64, PowerPC, S390x, SH4, x86, x86_64 * Compilers: Clang 3.0-9.0, GCC 4.6-8.2 * Runtimes: ObjFW macOS ----- * OS Versions: 10.5, 10.7-10.14, Darling |
︙ | ︙ |
Modified README.md from [826335256c] to [c2eecac5f0].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Table of Contents ================= * [Installation](#installation) * [macOS and iOS](#macos-and-ios) * [Building as a framework](#building-as-a-framework) * [Using the macOS or iOS framework in Xcode](#using-the-macos-or-ios-framework-in-xcode) * [Windows](#windows) * [Getting MSYS2](#getting-msys2) * [Updating MSYS2](#updating-msys2) * [Installing MinGW-w64 using MSYS2](#installing-mingw-w64-using-msys2) * [Getting, building and installing ObjFW](#getting-building-and-installing-objfw) * [Nintendo DS, Nintendo 3DS and Wii](#nintendo-ds-nintendo-3ds-and-wii) * [Nintendo DS](#nintendo-ds) | > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Table of Contents ================= * [Installation](#installation) * [macOS and iOS](#macos-and-ios) * [Building as a framework](#building-as-a-framework) * [Using the macOS or iOS framework in Xcode](#using-the-macos-or-ios-framework-in-xcode) * [Broken Xcode versions](#broken-xcode-versions) * [Windows](#windows) * [Getting MSYS2](#getting-msys2) * [Updating MSYS2](#updating-msys2) * [Installing MinGW-w64 using MSYS2](#installing-mingw-w64-using-msys2) * [Getting, building and installing ObjFW](#getting-building-and-installing-objfw) * [Nintendo DS, Nintendo 3DS and Wii](#nintendo-ds-nintendo-3ds-and-wii) * [Nintendo DS](#nintendo-ds) |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 | ### Using the macOS or iOS framework in Xcode To use the macOS framework in Xcode, you need to add the `.framework`s to your project and add the following flags to `Other C Flags`: -fconstant-string-class=OFConstantString -fno-constant-cfstrings Windows ------- Windows is only officially supported when following these instructions, as there are many MinGW versions that behave slightly differently and often cause problems. | > > > > > > > > > > > > > > > > > > > > > > > | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | ### Using the macOS or iOS framework in Xcode To use the macOS framework in Xcode, you need to add the `.framework`s to your project and add the following flags to `Other C Flags`: -fconstant-string-class=OFConstantString -fno-constant-cfstrings ### Broken Xcode versions Some versions of Xcode shipped with a version of Clang that ignores `-fconstant-string-class=OFConstantString`. This will manifest in an error like this: OFAllocFailedException.m:94:10: error: cannot find interface declaration for 'NSConstantString' return @"Allocating an object failed!"; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. 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. You can get older versions of Xcode [here](https://developer.apple.com/download) by clicking on "More" in the top-right corner. Windows ------- Windows is only officially supported when following these instructions, as there are many MinGW versions that behave slightly differently and often cause problems. |
︙ | ︙ |
Modified build-aux/m4/buildsys.m4 from [a231c1e9f4] to [90f081db1f].
︙ | ︙ | |||
180 181 182 183 184 185 186 | INSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i && cp -R $$i ${DESTDIR}${plugindir}/' UNINSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; mingw* | cygwin*) AC_MSG_RESULT(MinGW / Cygwin) LIB_CFLAGS='' | | | | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | INSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i && cp -R $$i ${DESTDIR}${plugindir}/' UNINSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; mingw* | cygwin*) AC_MSG_RESULT(MinGW / Cygwin) LIB_CFLAGS='' LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,lib${SHARED_LIB}.a' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='' LIB_SUFFIX='.dll' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.dll' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 lib$$i.a ${DESTDIR}${libdir}/lib$$i.a' UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$$i.a' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='${SHARED_LIB}.a' ;; openbsd* | mirbsd*) AC_MSG_RESULT(OpenBSD) LIB_CFLAGS='-fPIC -DPIC' |
︙ | ︙ |
Modified buildsys.mk.in from [4053db3b86] to [32c1d977cd].
︙ | ︙ | |||
123 124 125 126 127 128 129 | .SILENT: .SUFFIXES: .SUFFIXES: .amigalib.o .beam .c .cc .class .cxx .d .erl .lib.o .java .mo .m .mm .o .plugin.o .po .py .pyc .rc .S .xpm .PHONY: all subdirs subdirs-after pre-depend depend install install-extra uninstall uninstall-extra clean distclean locales copy-headers-into-framework ${SUBDIRS} ${SUBDIRS_AFTER} all: | | | | | | | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | .SILENT: .SUFFIXES: .SUFFIXES: .amigalib.o .beam .c .cc .class .cxx .d .erl .lib.o .java .mo .m .mm .o .plugin.o .po .py .pyc .rc .S .xpm .PHONY: all subdirs subdirs-after pre-depend depend install install-extra uninstall uninstall-extra clean distclean locales copy-headers-into-framework ${SUBDIRS} ${SUBDIRS_AFTER} all: ${MAKE} -s pre-all ${MAKE} -s subdirs ${MAKE} -s depend ${MAKE} -s ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${FRAMEWORK} ${FRAMEWORK_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales ${MAKE} -s subdirs-after ${MAKE} -s post-all pre-all post-all: subdirs: ${SUBDIRS} subdirs-after: ${SUBDIRS_AFTER} ${SUBDIRS} ${SUBDIRS_AFTER}: for i in $@; do \ ${DIR_ENTER}; \ ${MAKE} -s || exit $$?; \ ${DIR_LEAVE}; \ done depend: pre-depend : >.deps for i in ${DEPS}; do \ echo "-include \$${.CURDIR}/$$i" >>.deps; \ |
︙ | ︙ | |||
187 188 189 190 191 192 193 | else \ ${LINK_FAILED}; \ fi ${FRAMEWORK} ${FRAMEWORK_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LINK_STATUS} out="$@"; \ | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | else \ ${LINK_FAILED}; \ 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 \ ${LINK_OK}; \ else \ rm -fr $$out; false; \ ${LINK_FAILED}; \ fi copy-headers-into-framework: for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ cd $$i || exit 1; \ ${MAKE} -s copy-headers-into-framework || exit $$?; \ cd .. || exit 1; \ done if test x"${includesubdir}" = x"${COPY_HEADERS_IF_SUBDIR}"; then \ for i in "" ${INCLUDES}; do \ test x"$$i" = x"" && continue; \ ${MKDIR_P} ${COPY_HEADERS_DESTINATION} || exit $$?; \ |
︙ | ︙ | |||
609 610 611 612 613 614 615 | ${COMPILE_PLUGIN_FAILED}; \ fi install: all install-extra for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 | ${COMPILE_PLUGIN_FAILED}; \ fi install: all install-extra for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ ${MAKE} -s install || exit $$?; \ ${DIR_LEAVE}; \ done for i in "" ${SHARED_LIB}; do \ test x"$$i" = x"" && continue; \ ${INSTALL_STATUS}; \ if ${MKDIR_P} ${DESTDIR}${libdir} @INSTALL_LIB@; then \ |
︙ | ︙ | |||
722 723 724 725 726 727 728 | install-extra: uninstall: uninstall-extra for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ | | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | install-extra: uninstall: uninstall-extra for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ ${MAKE} -s uninstall || exit $$?; \ ${DIR_LEAVE}; \ done for i in "" ${SHARED_LIB}; do \ test x"$$i" = x"" && continue; \ if test -f ${DESTDIR}${libdir}/$$i; then \ if : @UNINSTALL_LIB@; then \ |
︙ | ︙ | |||
837 838 839 840 841 842 843 | uninstall-extra: clean: for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ | | | | | 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 | uninstall-extra: clean: for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ ${MAKE} -s clean || exit $$?; \ ${DIR_LEAVE}; \ done : >.deps for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \ test x"$$i" = x"" && continue; \ if test -f $$i -o -d $$i; then \ if rm -fr $$i; then \ ${DELETE_OK}; \ else \ ${DELETE_FAILED}; \ fi \ fi \ done distclean: clean for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ ${DIR_ENTER}; \ ${MAKE} -s distclean || exit $$?; \ ${DIR_LEAVE}; \ done for i in "" ${DISTCLEAN} .deps *~; do \ test x"$$i" = x"" && continue; \ if test -f $$i -o -d $$i; then \ if rm -fr $$i; then \ ${DELETE_OK}; \ else \ ${DELETE_FAILED}; \ fi \ fi \ done print-hierarchy: for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ test x"$$i" = x"" && continue; \ echo ${PRINT_HIERARCHY_PREFIX}$$i; \ cd $$i || exit $$?; \ ${MAKE} -s PRINT_HIERARCHY_PREFIX=$$i/ print-hierarchy || exit $$?; \ cd .. || exit $$?; \ done print-var: printf '%s\n' '${${VAR}}' DIR_ENTER = printf "@TERM_EL@@TERM_SETAF6@Entering directory @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF6@.@TERM_SGR0@\n" "$$i"; cd $$i || exit $$? |
︙ | ︙ |
Modified configure.ac from [3226ef7f8e] to [59df486ed4].
︙ | ︙ | |||
35 36 37 38 39 40 41 | OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags" LDFLAGS="$LDFLAGS $flags" enable_shared="no" enable_threads="no" enable_sockets="no" enable_files="no" | < < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags" LDFLAGS="$LDFLAGS $flags" enable_shared="no" enable_threads="no" enable_sockets="no" enable_files="no" ;; m68k-*-amigaos*) AS_IF([test x"$OBJCFLAGS" = x""], [ OBJCFLAGS="-O0" ]) OBJCFLAGS="$OBJCFLAGS -noixemul" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul" CPPFLAGS="$CPPFLAGS -D__NO_NET_API" LDFLAGS="$LDFLAGS -noixemul" enable_files="yes" # Required for reading ENV: enable_shared="no" supports_amiga_lib="yes" AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt68k.library) AC_SUBST(SFDC_TARGET, m68k-amigaos) AC_SUBST(SFD_FILE, amigaos3.sfd) AC_SUBST(SFDC_INLINE_H, inline.h) dnl For 68000, GCC emits calls to helper functions that |
︙ | ︙ | |||
420 421 422 423 424 425 426 427 | #include <stdlib.h> #if defined(__GLIBC__) || defined(__MINGW32__) || \ defined(__NEWLIB__) || defined(__MORPHOS__) egrep_cpp_yes #endif ], [ CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" | > | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | #include <stdlib.h> #if defined(__GLIBC__) || defined(__MINGW32__) || \ defined(__NEWLIB__) || defined(__MORPHOS__) egrep_cpp_yes #endif ], [ AC_MSG_RESULT(yes) CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" gnu_source="yes" ], [ AC_MSG_RESULT(no) ]) case "$host_os" in solaris*) CPPFLAGS="-D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS $CPPFLAGS" |
︙ | ︙ | |||
815 816 817 818 819 820 821 | AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) ]) ;; esac | < < > > > > > | < < < < < < < < < < < < < < < < < < | < < < < < | 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 | AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) ]) ;; esac AC_CHECK_LIB(m, fmod, LIBS="$LIBS -lm") AC_CHECK_LIB(complex, creal, TESTS_LIBS="$TESTS_LIBS -lcomplex") AC_CHECK_FUNC(asprintf, [ case "$host" in *-*-mingw*) dnl asprintf from MinGW is broken on older Windows dnl versions have_asprintf="no" ;; *-psp-*) dnl asprintf is broken on the PSP have_asprintf="no" ;; *) have_asprintf="yes" AC_DEFINE(HAVE_ASPRINTF, 1, [Whether we have asprintf()]) ;; esac ], [ have_asprintf="no" ]) AC_ARG_ENABLE(unicode-tables, AS_HELP_STRING([--disable-unicode-tables], [Disable Unicode tables])) AS_IF([test x"$enable_unicode_tables" != x"no"], [ AC_DEFINE(OF_HAVE_UNICODE_TABLES, 1, [Whether to build with Unicode tables]) AC_SUBST(UNICODE_M, "unicode.m") |
︙ | ︙ | |||
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 | ]) AC_CHECK_HEADERS(fcntl.h dirent.h) AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep fcntl]) AC_CHECK_HEADERS(xlocale.h) AC_CHECK_FUNCS([strtod_l strtof_l asprintf_l]) AC_CHECK_HEADERS(sys/utsname.h) AC_CHECK_FUNCS(uname) case "$host_os" in amigaos*) ;; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 | ]) AC_CHECK_HEADERS(fcntl.h dirent.h) AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep fcntl]) AC_CHECK_HEADERS(xlocale.h) AC_CHECK_FUNCS([strtod_l strtof_l asprintf_l]) AS_IF([test x"$gnu_source" != x"yes" -a \( \ x"$ac_cv_func_strtod_l" = x"yes" -o x"$ac_cv_func_strtof_l" = x"yes" -o \ x"$ac_cv_func_asprintf_l" = x"yes" \)], [ AC_MSG_CHECKING(whether *_l functions need _GNU_SOURCE) AC_TRY_COMPILE([ #include <stdlib.h> #include <stdio.h> #include <locale.h> #ifdef HAVE_XLOCALE_H # include <xlocale.h> #endif ], [ #ifdef HAVE_STRTOD_L (void)strtod_l; #endif #ifdef HAVE_STRTOF_L (void)strtof_l; #endif #ifdef HAVE_ASPRINTF_L (void)asprintf_l; #endif ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" ]) ]) dnl This check needs to happen after the above, as _GNU_SOURCE can change the dnl return type. AC_CHECK_FUNCS(strerror_r, [ AC_MSG_CHECKING(for return type of strerror_r) AC_TRY_COMPILE([ #include <stdio.h> #include <string.h> ], [ switch (strerror_r(0, NULL, 0)) { case 0:; } ], [ AC_MSG_RESULT(int) ], [ AC_MSG_RESULT(char *) AC_DEFINE(STRERROR_R_RETURNS_CHARP, 1, [Whether strerror_r returns char *]) ]) ]) AC_CHECK_HEADERS(sys/utsname.h) AC_CHECK_FUNCS(uname) case "$host_os" in amigaos*) ;; |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 | AC_DEFINE(OF_HAVE_NETINET_IN_H, 1, [Whether we have netinet/in.h]) ]) AC_CHECK_HEADER(netinet/tcp.h, [ AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1, [Whether we have netinet/tcp.h]) ]) AC_CHECK_HEADERS([arpa/inet.h netdb.h]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif | > > > > > > > > > > | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 | AC_DEFINE(OF_HAVE_NETINET_IN_H, 1, [Whether we have netinet/in.h]) ]) AC_CHECK_HEADER(netinet/tcp.h, [ AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1, [Whether we have netinet/tcp.h]) ]) AC_CHECK_HEADER(netinet/sctp.h, [ AC_DEFINE(OF_HAVE_SCTP, 1, [Whether we have SCTP]) AC_DEFINE(OF_HAVE_NETINET_SCTP_H, 1, [Whether we have netinet/sctp.h]) AC_SUBST(USE_SRCS_SCTP, '${SRCS_SCTP}') ]) AC_CHECK_HEADERS([arpa/inet.h netdb.h]) AC_CHECK_HEADER(netipx/ipx.h, [ AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1, [Whether we have netipx/ipx.h]) ]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif |
︙ | ︙ | |||
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 | # include <winsock2.h> # endif # endif # include <windows.h> # include <ws2tcpip.h> #endif ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | > | 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 | # include <winsock2.h> # endif # endif # include <windows.h> # include <ws2tcpip.h> #endif ]) AC_CHECK_MEMBER(struct sockaddr_ipx.sipx_network, [], [ AC_CHECK_MEMBER(struct sockaddr_ipx.sa_netnum, [], [], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_NETIPX_IPX_H # include <netipx/ipx.h> #endif #ifdef _WIN32 # ifdef __MINGW32__ # include <_mingw.h> # ifdef __MINGW64_VERSION_MAJOR # include <winsock2.h> # endif # endif # include <windows.h> # include <wsipx.h> #endif ]) ], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_NETIPX_IPX_H # include <netipx/ipx.h> #endif #ifdef _WIN32 # ifdef __MINGW32__ # include <_mingw.h> # ifdef __MINGW64_VERSION_MAJOR # include <winsock2.h> # endif # endif # include <windows.h> # include <wsipx.h> #endif ]) AS_IF([test x"$ac_cv_member_struct_sockaddr_ipx_sipx_network" = x"yes" \ -o x"$ac_cv_member_struct_sockaddr_ipx_sa_netnum" = x"yes"], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_SYS_SOCKET_H # include <sys/socket.h> #endif #ifdef _WIN32 # ifdef __MINGW32__ # include <_mingw.h> # ifdef __MINGW64_VERSION_MAJOR # include <winsock2.h> # endif # endif # include <windows.h> # include <wsipx.h> #endif #ifdef AF_IPX egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX]) AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}') ]) ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M, "OFKqueueKernelEventObserver.m") break ]) AC_CHECK_FUNCS(epoll_create1 epoll_create, [ AC_DEFINE(HAVE_EPOLL, 1, [Whether we have epoll]) AC_SUBST(OF_EPOLL_KERNEL_EVENT_OBSERVER_M, "OFEpollKernelEventObserver.m") break ]) AS_IF([test x"$with_wii" = x"yes"], [ AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()]) AC_SUBST(OF_POLL_KERNEL_EVENT_OBSERVER_M, "OFPollKernelEventObserver.m") ], [ AC_CHECK_HEADERS(poll.h) AC_CHECK_FUNC(poll, [ AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()]) AC_SUBST(OF_POLL_KERNEL_EVENT_OBSERVER_M, "OFPollKernelEventObserver.m") ]) ]) case "$host_os" in amigaos* | mingw* | morphos*) AC_DEFINE(HAVE_SELECT, 1, [Whether we have select() or similar]) AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M, "OFSelectKernelEventObserver.m") ;; *) AC_CHECK_HEADERS(sys/select.h) AC_CHECK_FUNC(select, [ AC_DEFINE(HAVE_SELECT, 1, [Whether we have select() or similar]) AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M, "OFSelectKernelEventObserver.m") ]) ;; esac AS_IF([test x"$enable_threads" != x"no"], [ AC_SUBST(OF_HTTP_CLIENT_TESTS_M, "OFHTTPClientTests.m") ]) AC_SUBST(OFDNS, "ofdns") AS_IF([test x"$enable_files" != x"no"], [ AC_SUBST(OFHTTP, "ofhttp") ]) AC_SUBST(OFSOCK, "ofsock") ]) AC_DEFUN([CHECK_BUILTIN_BSWAP], [ AC_MSG_CHECKING(for __builtin_bswap$1) AC_TRY_LINK([ #include <stdint.h> #include <stdio.h> |
︙ | ︙ | |||
1437 1438 1439 1440 1441 1442 1443 | ], [ break ]) ]) ;; esac AS_IF([test x"$have_processes" = x"yes"], [ | | > | 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 | ], [ break ]) ]) ;; esac AS_IF([test x"$have_processes" = x"yes"], [ AC_SUBST(OF_PROCESS_M, "OFProcess.m") AC_DEFINE(OF_HAVE_PROCESSES, 1, [Whether we have processes]) ]) AC_CHECK_HEADERS_ONCE([complex.h sys/ioctl.h sys/ttycom.h]) AC_CHECK_FUNCS(isatty) AC_CHECK_FUNC(pledge, [ AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()]) ]) AS_IF([test x"$objc_runtime" = x"Apple runtime"], [ AC_CHECK_HEADER(Foundation/NSObject.h, [ |
︙ | ︙ | |||
1477 1478 1479 1480 1481 1482 1483 | old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Xclang -fblocks" AC_TRY_COMPILE([], [ int (^foo)(int bar); foo = ^ (int bar) { return 0; } ], [ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -Xclang -fblocks" | | | 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 | old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Xclang -fblocks" AC_TRY_COMPILE([], [ int (^foo)(int bar); foo = ^ (int bar) { return 0; } ], [ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -Xclang -fblocks" AC_SUBST(OF_BLOCK_TESTS_M, "OFBlockTests.m") AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) OBJCFLAGS="$old_OBJCFLAGS" ]) AS_IF([test x"$GOBJC" = x"yes"], [ |
︙ | ︙ |
Modified extra.mk.in from [0ce90d018a] to [45f41009ef].
︙ | ︙ | |||
50 51 52 53 54 55 56 | LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OFARC = @OFARC@ | < < > | | > > | | | | > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFSOCK = @OFSOCK@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ OF_HTTP_CLIENT_TESTS_M = @OF_HTTP_CLIENT_TESTS_M@ OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@ OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@ OF_PROCESS_M = @OF_PROCESS_M@ 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_FRAMEWORK_LIBS = @RUNTIME_FRAMEWORK_LIBS@ RUNTIME_LIBS = @RUNTIME_LIBS@ RUN_TESTS = @RUN_TESTS@ SFDC_INLINE_H = @SFDC_INLINE_H@ SFDC_TARGET = @SFDC_TARGET@ SFD_FILE = @SFD_FILE@ TESTPLUGIN = @TESTPLUGIN@ TESTPLUGIN_LIBS = @TESTPLUGIN_LIBS@ TESTS_LIBS = @TESTS_LIBS@ TESTS_STATIC_LIB = @TESTS_STATIC_LIB@ UNICODE_M = @UNICODE_M@ USE_INCLUDES_ATOMIC = @USE_INCLUDES_ATOMIC@ USE_SRCS_FILES = @USE_SRCS_FILES@ USE_SRCS_IPX = @USE_SRCS_IPX@ USE_SRCS_PLUGINS = @USE_SRCS_PLUGINS@ USE_SRCS_SCTP = @USE_SRCS_SCTP@ USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@ USE_SRCS_THREADS = @USE_SRCS_THREADS@ USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@ WRAPPER = @WRAPPER@ |
Modified generators/Makefile from [3ca3993514] to [0e25880b06].
1 2 3 4 5 6 7 8 9 | include ../extra.mk PROG_NOINST = gen_tables${PROG_SUFFIX} SRCS = TableGenerator.m .PHONY: run run: all rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | include ../extra.mk PROG_NOINST = gen_tables${PROG_SUFFIX} SRCS = TableGenerator.m .PHONY: run run: all rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt.dll libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../src/libobjfw.so; then \ ${LN_S} ../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../src/objfw.dll; then \ ${LN_S} ../src/objfw.dll objfw.dll; \ fi if test -f ../src/libobjfw.dylib; then \ ${LN_S} ../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../src/runtime/libobjfwrt.so; then \ ${LN_S} ../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../src/runtime/objfwrt.dll; then \ ${LN_S} ../src/runtime/objfwrt.dll objfwrt.dll; \ fi if test -f ../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_FRAMEWORK_PATH=../src:../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \ 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.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f objfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} objfwrt.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT include ../buildsys.mk CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. LIBS := -L../src -lobjfw -L../src/runtime ${RUNTIME_LIBS} ${LIBS} LD = ${OBJC} |
Modified src/Makefile from [d8e8488c9d] to [e69692586b].
︙ | ︙ | |||
51 52 53 54 55 56 57 | OFNull.m \ OFNumber.m \ OFObject.m \ OFObject+KeyValueCoding.m \ OFObject+Serialization.m \ OFOptionsParser.m \ OFPair.m \ | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | OFNull.m \ OFNumber.m \ OFObject.m \ OFObject+KeyValueCoding.m \ OFObject+Serialization.m \ OFOptionsParser.m \ OFPair.m \ ${OF_PROCESS_M} \ OFRIPEMD160Hash.m \ OFRunLoop.m \ OFSandbox.m \ OFSecureData.m \ OFSeekableStream.m \ OFSet.m \ OFSHA1Hash.m \ |
︙ | ︙ | |||
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | ${USE_SRCS_THREADS} \ ${USE_SRCS_WINDOWS} SRCS_FILES = OFFile.m \ OFINICategory.m \ OFINIFile.m \ OFSettings.m \ OFString+PathAdditions.m SRCS_PLUGINS = OFPlugin.m SRCS_SOCKETS = OFDNSQuery.m \ OFDNSResolver.m \ OFDNSResourceRecord.m \ OFDNSResponse.m \ OFHTTPClient.m \ OFHTTPCookie.m \ OFHTTPCookieManager.m \ OFHTTPRequest.m \ OFHTTPResponse.m \ OFHTTPServer.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFUDPSocket.m \ | > > > > > > | > > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | ${USE_SRCS_THREADS} \ ${USE_SRCS_WINDOWS} SRCS_FILES = OFFile.m \ OFINICategory.m \ OFINIFile.m \ OFSettings.m \ OFString+PathAdditions.m SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_PLUGINS = OFPlugin.m SRCS_SCTP = OFSCTPSocket.m SRCS_SOCKETS = OFDNSQuery.m \ OFDNSResolver.m \ OFDNSResourceRecord.m \ OFDNSResponse.m \ OFDatagramSocket.m \ OFHTTPClient.m \ OFHTTPCookie.m \ OFHTTPCookieManager.m \ OFHTTPRequest.m \ OFHTTPResponse.m \ OFHTTPServer.m \ OFSequencedPacketSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFUDPSocket.m \ socket.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_SCTP} SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFRecursiveMutex.m \ condition.m \ mutex.m \ thread.m \ tlskey.m |
︙ | ︙ | |||
194 195 196 197 198 199 200 201 | OFUTF8String.m \ ${LIBBASES_M} SRCS_FILES += OFFileURLHandler.m \ OFINIFileSettings.m SRCS_SOCKETS += OFDNSResolverSettings.m \ OFHTTPURLHandler.m \ OFHostAddressResolver.m \ OFKernelEventObserver.m \ | > | | | | > | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | OFUTF8String.m \ ${LIBBASES_M} SRCS_FILES += OFFileURLHandler.m \ OFINIFileSettings.m SRCS_SOCKETS += OFDNSResolverSettings.m \ OFHTTPURLHandler.m \ OFHostAddressResolver.m \ OFIPSocketAsyncConnector.m \ OFKernelEventObserver.m \ ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \ ${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \ ${OF_POLL_KERNEL_EVENT_OBSERVER_M} \ ${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \ OFTCPSocketSOCKS5Connector.m OBJS_EXTRA = ${RUNTIME_RUNTIME_A} \ ${EXCEPTIONS_EXCEPTIONS_A} \ ${ENCODINGS_ENCODINGS_A} \ ${FORWARDING_FORWARDING_A} LIB_OBJS_EXTRA = ${RUNTIME_RUNTIME_LIB_A} \ ${EXCEPTIONS_EXCEPTIONS_LIB_A} \ |
︙ | ︙ |
Modified src/OFApplication.h from [d0ae1ccee1] to [ae508719d0].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | */ #include <signal.h> #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @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; #define OF_APPLICATION_DELEGATE(class_) \ int \ main(int argc, char *argv[]) \ { \ return of_application_main(&argc, &argv, \ (class_ *)[[class_ alloc] init]); \ } | > > > > > > > > > > > > > > > > > > > > > > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | */ #include <signal.h> #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN /*! @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. * * For example, it can be used like this: * * @code * // In MyAppDelegate.h: * @interface MyAppDelegate: OFObject <OFApplicationDelegate> * @end * * // In MyAppDelegate.m: * OF_APPLICATION_DELEGATE(MyAppDelegate) * * @implementation MyAppDelegate * - (void)applicationDidFinishLaunching * { * [OFApplication terminate]; * } * @end * @endcode */ #define OF_APPLICATION_DELEGATE(class_) \ int \ main(int argc, char *argv[]) \ { \ return of_application_main(&argc, &argv, \ (class_ *)[[class_ alloc] init]); \ } |
︙ | ︙ |
Modified src/OFApplication.m from [7b2e9f847b] to [2e614ff495].
︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #endif #import "OFLocale.h" #import "OFPair.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #import "OFSandbox.h" #import "OFString.h" #import "OFThread+Private.h" #import "OFThread.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFSandboxActivationFailedException.h" | > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #endif #import "OFLocale.h" #import "OFPair.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #import "OFSandbox.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFThread+Private.h" #import "OFThread.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFSandboxActivationFailedException.h" |
︙ | ︙ | |||
108 109 110 111 112 113 114 | int wargc, si = 0; #endif [[OFLocale alloc] init]; app = [[OFApplication alloc] of_init]; | < < < > | | | > > > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | int wargc, si = 0; #endif [[OFLocale alloc] init]; app = [[OFApplication alloc] of_init]; #ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) { __wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si); [app of_setArgumentCount: wargc andWideArgumentValues: wargv]; } else #endif [app of_setArgumentCount: argc andArgumentValues: argv]; app.delegate = delegate; [app of_run]; [delegate release]; |
︙ | ︙ | |||
220 221 222 223 224 225 226 | @try { _environment = [[OFMutableDictionary alloc] init]; atexit(atexitHandler); #if defined(OF_WINDOWS) | > | | | | | | | | | | | | | | | | | | | | | > | | | | | > | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | @try { _environment = [[OFMutableDictionary alloc] init]; atexit(atexitHandler); #if defined(OF_WINDOWS) if ([OFSystemInfo isWindowsNT]) { of_char16_t *env, *env0; env = env0 = GetEnvironmentStringsW(); while (*env != 0) { void *pool = objc_autoreleasePoolPush(); OFString *tmp, *key, *value; size_t length, pos; length = of_string_utf16_length(env); tmp = [OFString stringWithUTF16String: env length: length]; env += length + 1; /* * cmd.exe seems to add some special variables * which start with a "=", even though variable * names are not allowed to contain a "=". */ if ([tmp hasPrefix: @"="]) { objc_autoreleasePoolPop(pool); continue; } pos = [tmp rangeOfString: @"="].location; if (pos == OF_NOT_FOUND) { fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", tmp.UTF8String); continue; } key = [tmp substringWithRange: of_range(0, pos)]; value = [tmp substringWithRange: of_range(pos + 1, tmp.length - pos - 1)]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } FreeEnvironmentStringsW(env0); } else { char *env, *env0; env = env0 = GetEnvironmentStringsA(); while (*env != 0) { void *pool = objc_autoreleasePoolPush(); OFString *tmp, *key, *value; size_t length, pos; length = strlen(env); tmp = [OFString stringWithCString: env encoding: [OFLocale encoding] length: length]; env += length + 1; /* * cmd.exe seems to add some special variables * which start with a "=", even though variable * names are not allowed to contain a "=". */ if ([tmp hasPrefix: @"="]) { objc_autoreleasePoolPop(pool); continue; } pos = [tmp rangeOfString: @"="].location; if (pos == OF_NOT_FOUND) { fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", tmp.UTF8String); continue; } key = [tmp substringWithRange: of_range(0, pos)]; value = [tmp substringWithRange: of_range(pos + 1, tmp.length - pos - 1)]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } FreeEnvironmentStringsA(env0); } #elif defined(OF_AMIGAOS) void *pool = objc_autoreleasePoolPush(); OFFileManager *fileManager = [OFFileManager defaultManager]; OFArray *envContents = [fileManager contentsOfDirectoryAtPath: @"ENV:"]; const of_string_encoding_t encoding = [OFLocale encoding]; struct Process *proc; |
︙ | ︙ | |||
434 435 436 437 438 439 440 | [super dealloc]; } - (void)of_setArgumentCount: (int *)argc andArgumentValues: (char ***)argv { | < | | | < | < < < < | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | [super dealloc]; } - (void)of_setArgumentCount: (int *)argc andArgumentValues: (char ***)argv { void *pool = objc_autoreleasePoolPush(); OFMutableArray *arguments; of_string_encoding_t encoding; _argc = argc; _argv = argv; encoding = [OFLocale encoding]; #ifndef OF_NINTENDO_DS if (*argc > 0) { #else if (__system_argv->argvMagic == ARGV_MAGIC && __system_argv->argc > 0) { #endif _programName = [[OFString alloc] initWithCString: (*argv)[0] encoding: encoding]; arguments = [[OFMutableArray alloc] init]; _arguments = arguments; for (int i = 1; i < *argc; i++) [arguments addObject: [OFString stringWithCString: (*argv)[i] encoding: encoding]]; [arguments makeImmutable]; } objc_autoreleasePoolPop(pool); } #ifdef OF_WINDOWS - (void)of_setArgumentCount: (int)argc andWideArgumentValues: (wchar_t **)argv { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ |
Modified src/OFArray.h from [fea61523da] to [82b5ea76b0].
︙ | ︙ | |||
384 385 386 387 388 389 390 | 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 | | | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | 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:]. * @param options The options to use when sorting the array.@n * Possible values are: * Value | Description * ---------------------------|------------------------- * `OF_ARRAY_SORT_DESCENDING` | Sort in descending order * @return A sorted copy of the array */ |
︙ | ︙ |
Modified src/OFCharacterSet.m from [6367b81058] to [7a7a3d4551].
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "config.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFInvertedCharacterSet.h" #import "OFRangeCharacterSet.h" static struct { Class isa; } placeholder; static OFCharacterSet *whitespaceCharacterSet = nil; | > > > > > > > > > | < | | < < > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include "config.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFInvertedCharacterSet.h" #import "OFRangeCharacterSet.h" #import "once.h" @interface OFPlaceholderCharacterSet: OFCharacterSet @end @interface OFWhitespaceCharacterSet: OFCharacterSet @end static struct { Class isa; } placeholder; static OFCharacterSet *whitespaceCharacterSet = nil; static void initWhitespaceCharacterSet(void) { whitespaceCharacterSet = [[OFWhitespaceCharacterSet alloc] init]; } @implementation OFPlaceholderCharacterSet - (instancetype)init { return (id)[[OFBitSetCharacterSet alloc] init]; } |
︙ | ︙ | |||
98 99 100 101 102 103 104 | + (instancetype)characterSetWithRange: (of_range_t)range { return [[[self alloc] initWithRange: range] autorelease]; } + (OFCharacterSet *)whitespaceCharacterSet { | > > > | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | + (instancetype)characterSetWithRange: (of_range_t)range { return [[[self alloc] initWithRange: range] autorelease]; } + (OFCharacterSet *)whitespaceCharacterSet { static of_once_t onceControl = OF_ONCE_INIT; of_once(&onceControl, initWhitespaceCharacterSet); return whitespaceCharacterSet; } - (instancetype)init { if ([self isMemberOfClass: [OFCharacterSet class]]) { @try { [self doesNotRecognizeSelector: _cmd]; |
︙ | ︙ | |||
135 136 137 138 139 140 141 | { OF_UNRECOGNIZED_SELECTOR } - (OFCharacterSet *)invertedSet { return [[[OFInvertedCharacterSet alloc] | | < < < < < < < < < < < < < < < < < < < < < < < | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | { OF_UNRECOGNIZED_SELECTOR } - (OFCharacterSet *)invertedSet { return [[[OFInvertedCharacterSet alloc] initWithCharacterSet: self] autorelease]; } @end @implementation OFWhitespaceCharacterSet - (instancetype)autorelease { return self; } - (instancetype)retain { |
︙ | ︙ |
Modified src/OFColor.h from [53dfa6424a] to [59ecd06578].
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | */ @interface OFColor: OFObject { float _red, _green, _blue, _alpha; OF_RESERVE_IVARS(4) } /*! * @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 * @param blue The blue value of the color, between 0.0 and 1.0 * @param alpha The alpha value of the color, between 0.0 and 1.0 * @return A new color with the specified red, green, blue and alpha value */ + (instancetype)colorWithRed: (float)red green: (float)green blue: (float)blue alpha: (float)alpha; /*! * @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 * @param blue The blue value of the color, between 0.0 and 1.0 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | */ @interface OFColor: OFObject { float _red, _green, _blue, _alpha; OF_RESERVE_IVARS(4) } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFColor *black; @property (class, readonly, nonatomic) OFColor *silver; @property (class, readonly, nonatomic) OFColor *grey; @property (class, readonly, nonatomic) OFColor *white; @property (class, readonly, nonatomic) OFColor *maroon; @property (class, readonly, nonatomic) OFColor *red; @property (class, readonly, nonatomic) OFColor *purple; @property (class, readonly, nonatomic) OFColor *fuchsia; @property (class, readonly, nonatomic) OFColor *green; @property (class, readonly, nonatomic) OFColor *lime; @property (class, readonly, nonatomic) OFColor *olive; @property (class, readonly, nonatomic) OFColor *yellow; @property (class, readonly, nonatomic) OFColor *navy; @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 * @param blue The blue value of the color, between 0.0 and 1.0 * @param alpha The alpha value of the color, between 0.0 and 1.0 * @return A new color with the specified red, green, blue and alpha value */ + (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 * @param blue The blue value of the color, between 0.0 and 1.0 |
︙ | ︙ |
Modified src/OFColor.m from [c54ddadacf] to [eeffafbeab].
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFColor.h" #import "OFInvalidArgumentException.h" @implementation OFColor + (instancetype)colorWithRed: (float)red green: (float)green blue: (float)blue alpha: (float)alpha { return [[[self alloc] initWithRed: red green: green | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFColor.h" #import "once.h" #import "OFInvalidArgumentException.h" @implementation OFColor #define PREDEFINED_COLOR(name, r, g, b) \ static OFColor *name##Color = nil; \ \ static void \ initPredefinedColor_##name(void) \ { \ name##Color = [[OFColor alloc] initWithRed: r \ green: g \ blue: b \ alpha: 1]; \ } \ \ + (OFColor *)name \ { \ static of_once_t onceControl = OF_ONCE_INIT; \ 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) + (instancetype)colorWithRed: (float)red green: (float)green blue: (float)blue alpha: (float)alpha { return [[[self alloc] initWithRed: red green: green |
︙ | ︙ | |||
82 83 84 85 86 87 88 | return true; } - (uint32_t)hash { uint32_t hash; | < | < < | | | | | | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | return true; } - (uint32_t)hash { uint32_t hash; float tmp; OF_HASH_INIT(hash); tmp = OF_BSWAP_FLOAT_IF_LE(_red); for (uint_fast8_t i = 0; i < sizeof(float); i++) OF_HASH_ADD(hash, ((char *)&tmp)[i]); tmp = OF_BSWAP_FLOAT_IF_LE(_green); for (uint_fast8_t i = 0; i < sizeof(float); i++) OF_HASH_ADD(hash, ((char *)&tmp)[i]); tmp = OF_BSWAP_FLOAT_IF_LE(_blue); for (uint_fast8_t i = 0; i < sizeof(float); i++) OF_HASH_ADD(hash, ((char *)&tmp)[i]); tmp = OF_BSWAP_FLOAT_IF_LE(_alpha); for (uint_fast8_t i = 0; i < sizeof(float); i++) OF_HASH_ADD(hash, ((char *)&tmp)[i]); OF_HASH_FINALIZE(hash); return hash; } - (void)getRed: (float *)red |
︙ | ︙ |
Modified src/OFConstantString.h from [a28a2410f5] to [b16809eb56].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * 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. */ | > > > | > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | * * 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. */ #ifndef OBJFW_OF_CONSTANT_STRING_H #define OBJFW_OF_CONSTANT_STRING_H #include "OFString.h" OF_ASSUME_NONNULL_BEGIN #if !defined(OF_CONSTANT_STRING_M) && \ defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__) # ifdef __cplusplus extern "C" { # endif extern void *_OFConstantStringClassReference; # ifdef __cplusplus } # endif #endif #ifdef __OBJC__ /*! * @class OFConstantString OFConstantString.h ObjFW/OFConstantString.h * * @brief A class for storing constant strings using the `@""` literal. */ OF_SUBCLASSING_RESTRICTED @interface OFConstantString: OFString { char *_cString; unsigned int _cStringLength; } @end #endif OF_ASSUME_NONNULL_END #endif |
Modified src/OFConstantString.m from [743f51b49a] to [1a9a1e4686].
︙ | ︙ | |||
670 671 672 673 674 675 676 677 678 679 680 681 682 683 | - (OFString *)decomposedStringWithCompatibilityMapping { [self finishInitialization]; return self.decomposedStringWithCompatibilityMapping; } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self finishInitialization]; [self writeToFile: path]; | > > > > > > > > > | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 | - (OFString *)decomposedStringWithCompatibilityMapping { [self finishInitialization]; return self.decomposedStringWithCompatibilityMapping; } #endif #ifdef OF_WINDOWS - (OFString *)stringByExpandingWindowsEnvironmentStrings { [self finishInitialization]; return self.stringByExpandingWindowsEnvironmentStrings; } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self finishInitialization]; [self writeToFile: path]; |
︙ | ︙ |
Modified src/OFDNSResolver.h from [8e72b091f6] to [074bf54ace].
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | @class OFDNSResolver; @class OFDNSResolverContext; @class OFDNSResolverSettings; @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFNumber; @class OFUDPSocket; /*! * @enum of_dns_resolver_error_t OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief An enum describing why resolving a host failed. */ | > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | @class OFDNSResolver; @class OFDNSResolverContext; @class OFDNSResolverSettings; @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @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. */ |
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 | OFUDPSocket *_IPv4Socket; #ifdef OF_HAVE_IPV6 OFUDPSocket *_IPv6Socket; #endif char _buffer[OF_DNS_RESOLVER_BUFFER_LENGTH]; OFMutableDictionary OF_GENERIC(OFNumber *, OFDNSResolverContext *) *_queries; } /*! * @brief A dictionary of static hosts. * * This dictionary is checked before actually looking up a host. */ | > > | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | OFUDPSocket *_IPv4Socket; #ifdef OF_HAVE_IPV6 OFUDPSocket *_IPv6Socket; #endif char _buffer[OF_DNS_RESOLVER_BUFFER_LENGTH]; OFMutableDictionary OF_GENERIC(OFNumber *, OFDNSResolverContext *) *_queries; OFMutableDictionary OF_GENERIC(OFTCPSocket *, OFDNSResolverContext *) *_TCPQueries; } /*! * @brief A dictionary of static hosts. * * This dictionary is checked before actually looking up a host. */ |
︙ | ︙ |
Modified src/OFDNSResolver.m from [8f5030468c] to [5d30f91158].
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #import "OFData.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFHostAddressResolver.h" #import "OFNumber.h" #import "OFPair.h" #import "OFString.h" #import "OFTimer.h" #import "OFUDPSocket.h" #import "OFUDPSocket+Private.h" #import "OFDNSQueryFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #ifndef SOCK_DNS # define SOCK_DNS 0 #endif #define BUFFER_LENGTH OF_DNS_RESOLVER_BUFFER_LENGTH /* * RFC 1035 doesn't specify if pointers to pointers are allowed, and if so how * many. Since it's unspecified, we have to assume that it might happen, but we * also want to limit it to avoid DoS. Limiting it to 16 levels of pointers and * immediately rejecting pointers to itself seems like a fair balance. */ #define MAX_ALLOWED_POINTERS 16 #define CNAME_RECURSION 3 | > > < < < < < < | > > > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #import "OFData.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFHostAddressResolver.h" #import "OFNumber.h" #import "OFPair.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFTimer.h" #import "OFUDPSocket.h" #import "OFUDPSocket+Private.h" #import "OFDNSQueryFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #ifndef SOCK_DNS # define SOCK_DNS 0 #endif #define BUFFER_LENGTH OF_DNS_RESOLVER_BUFFER_LENGTH #define MAX_DNS_RESPONSE_LENGTH 65536 /* * RFC 1035 doesn't specify if pointers to pointers are allowed, and if so how * many. Since it's unspecified, we have to assume that it might happen, but we * also want to limit it to avoid DoS. Limiting it to 16 levels of pointers and * immediately rejecting pointers to itself seems like a fair balance. */ #define MAX_ALLOWED_POINTERS 16 #define CNAME_RECURSION 3 @interface OFDNSResolver () <OFUDPSocketDelegate, OFTCPSocketDelegate> - (void)of_contextTimedOut: (OFDNSResolverContext *)context; @end @interface OFDNSResolverContext: OFObject { @public OFDNSQuery *_query; OFNumber *_ID; OFDNSResolverSettings *_settings; size_t _nameServersIndex; unsigned int _attempt; id <OFDNSResolverQueryDelegate> _delegate; OFData *_queryData; of_socket_address_t _usedNameServer; OFTCPSocket *_TCPSocket; OFMutableData *_TCPQueryData; void *_TCPBuffer; size_t _responseLength; OFTimer *_cancelTimer; } - (instancetype)initWithQuery: (OFDNSQuery *)query ID: (OFNumber *)ID settings: (OFDNSResolverSettings *)settings delegate: (id <OFDNSResolverQueryDelegate>)delegate; |
︙ | ︙ | |||
309 310 311 312 313 314 315 | return [[[OFMXDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass preference: preference mailExchange: mailExchange TTL: TTL] autorelease]; } else if (recordType == OF_DNS_RECORD_TYPE_TXT) { | > > > > > > > > > > > | > > > | > > > | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | return [[[OFMXDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass preference: preference mailExchange: mailExchange TTL: TTL] autorelease]; } else if (recordType == OF_DNS_RECORD_TYPE_TXT) { OFMutableArray *textStrings = [OFMutableArray array]; while (dataLength > 0) { uint_fast8_t stringLength = buffer[i++]; dataLength--; if (stringLength > dataLength) @throw [OFInvalidServerReplyException exception]; [textStrings addObject: [OFData dataWithItems: buffer + i count: stringLength]]; i += stringLength; dataLength -= stringLength; } [textStrings makeImmutable]; return [[[OFTXTDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass textStrings: textStrings TTL: TTL] autorelease]; } else if (recordType == OF_DNS_RECORD_TYPE_RP) { size_t j = i; OFString *mailbox = parseName(buffer, length, &j, MAX_ALLOWED_POINTERS); OFString *TXTDomainName; |
︙ | ︙ | |||
535 536 537 538 539 540 541 542 543 544 545 546 547 548 | - (void)dealloc { [_query release]; [_ID release]; [_settings release]; [_delegate release]; [_queryData release]; [_cancelTimer release]; [super dealloc]; } @end @implementation OFDNSResolver | > > | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | - (void)dealloc { [_query release]; [_ID release]; [_settings release]; [_delegate release]; [_queryData release]; [_TCPSocket release]; [_TCPQueryData release]; [_cancelTimer release]; [super dealloc]; } @end @implementation OFDNSResolver |
︙ | ︙ | |||
566 567 568 569 570 571 572 573 574 575 576 577 578 579 | - (instancetype)init { self = [super init]; @try { _settings = [[OFDNSResolverSettings alloc] init]; _queries = [[OFMutableDictionary alloc] init]; [_settings reload]; } @catch (id e) { [self release]; @throw e; } | > | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | - (instancetype)init { self = [super init]; @try { _settings = [[OFDNSResolverSettings alloc] init]; _queries = [[OFMutableDictionary alloc] init]; _TCPQueries = [[OFMutableDictionary alloc] init]; [_settings reload]; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
588 589 590 591 592 593 594 595 596 597 598 599 600 601 | [_IPv4Socket cancelAsyncRequests]; [_IPv4Socket release]; #ifdef OF_HAVE_IPV6 [_IPv6Socket cancelAsyncRequests]; [_IPv6Socket release]; #endif [_queries release]; [super dealloc]; } - (OFDictionary *)staticHosts { return _settings->_staticHosts; | > | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | [_IPv4Socket cancelAsyncRequests]; [_IPv4Socket release]; #ifdef OF_HAVE_IPV6 [_IPv6Socket cancelAsyncRequests]; [_IPv6Socket release]; #endif [_queries release]; [_TCPQueries release]; [super dealloc]; } - (OFDictionary *)staticHosts { return _settings->_staticHosts; |
︙ | ︙ | |||
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | } - (void)of_sendQueryForContext: (OFDNSResolverContext *)context runLoopMode: (of_run_loop_mode_t)runLoopMode { OFUDPSocket *sock; OFString *nameServer; [context->_cancelTimer invalidate]; [context->_cancelTimer release]; context->_cancelTimer = nil; context->_cancelTimer = [[OFTimer alloc] initWithFireDate: [OFDate dateWithTimeIntervalSinceNow: context->_settings->_timeout] interval: context->_settings->_timeout target: self selector: @selector(of_contextTimedOut:) object: context repeats: false]; [[OFRunLoop currentRunLoop] addTimer: context->_cancelTimer forMode: runLoopMode]; nameServer = [context->_settings->_nameServers objectAtIndex: context->_nameServersIndex]; context->_usedNameServer = of_socket_address_parse_ip(nameServer, 53); switch (context->_usedNameServer.family) { #ifdef OF_HAVE_IPV6 case OF_SOCKET_ADDRESS_FAMILY_IPV6: if (_IPv6Socket == nil) { of_socket_address_t address = of_socket_address_parse_ip(@"::", 0); _IPv6Socket = [[OFUDPSocket alloc] init]; [_IPv6Socket of_bindToAddress: &address extraType: SOCK_DNS]; | > > > > > > > > > > > > > > > > > > | | | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 | } - (void)of_sendQueryForContext: (OFDNSResolverContext *)context runLoopMode: (of_run_loop_mode_t)runLoopMode { OFUDPSocket *sock; OFString *nameServer; [_queries setObject: context forKey: context->_ID]; [context->_cancelTimer invalidate]; [context->_cancelTimer release]; context->_cancelTimer = nil; context->_cancelTimer = [[OFTimer alloc] initWithFireDate: [OFDate dateWithTimeIntervalSinceNow: context->_settings->_timeout] interval: context->_settings->_timeout target: self selector: @selector(of_contextTimedOut:) object: context repeats: false]; [[OFRunLoop currentRunLoop] addTimer: context->_cancelTimer forMode: runLoopMode]; nameServer = [context->_settings->_nameServers objectAtIndex: context->_nameServersIndex]; if (context->_settings->_usesTCP) { OF_ENSURE(context->_TCPSocket == nil); context->_TCPSocket = [[OFTCPSocket alloc] init]; [_TCPQueries setObject: context forKey: context->_TCPSocket]; context->_TCPSocket.delegate = self; [context->_TCPSocket asyncConnectToHost: nameServer port: 53 runLoopMode: runLoopMode]; return; } context->_usedNameServer = of_socket_address_parse_ip(nameServer, 53); switch (context->_usedNameServer.family) { #ifdef OF_HAVE_IPV6 case OF_SOCKET_ADDRESS_FAMILY_IPV6: if (_IPv6Socket == nil) { of_socket_address_t address = of_socket_address_parse_ip(@"::", 0); _IPv6Socket = [[OFUDPSocket alloc] init]; [_IPv6Socket of_bindToAddress: &address extraType: SOCK_DNS]; _IPv6Socket.canBlock = false; _IPv6Socket.delegate = self; } sock = _IPv6Socket; break; #endif case OF_SOCKET_ADDRESS_FAMILY_IPV4: if (_IPv4Socket == nil) { of_socket_address_t address = of_socket_address_parse_ip(@"0.0.0.0", 0); _IPv4Socket = [[OFUDPSocket alloc] init]; [_IPv4Socket of_bindToAddress: &address extraType: SOCK_DNS]; _IPv4Socket.canBlock = false; _IPv4Socket.delegate = self; } sock = _IPv4Socket; break; default: @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
781 782 783 784 785 786 787 | @throw [OFOutOfRangeException exception]; context = [[[OFDNSResolverContext alloc] initWithQuery: query ID: ID settings: _settings delegate: delegate] autorelease]; | < < < > > > > > > > > > > | < | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | @throw [OFOutOfRangeException exception]; context = [[[OFDNSResolverContext alloc] initWithQuery: query ID: ID settings: _settings delegate: delegate] autorelease]; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } - (void)of_contextTimedOut: (OFDNSResolverContext *)context { of_run_loop_mode_t runLoopMode = [OFRunLoop currentRunLoop].currentMode; OFDNSQueryFailedException *exception; if (context->_TCPSocket != nil) { context->_TCPSocket.delegate = nil; [context->_TCPSocket cancelAsyncRequests]; [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; } if (context->_nameServersIndex + 1 < context->_settings->_nameServers.count) { context->_nameServersIndex++; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return; } if (++context->_attempt < context->_settings->_maxAttempts) { context->_nameServersIndex = 0; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return; } context = [[context retain] autorelease]; |
︙ | ︙ | |||
839 840 841 842 843 844 845 | @selector(resolver:didPerformQuery:response:exception:)]) [context->_delegate resolver: self didPerformQuery: context->_query response: nil exception: exception]; } | < | | | < < > < < < > > > | | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | @selector(resolver:didPerformQuery:response:exception:)]) [context->_delegate resolver: self didPerformQuery: context->_query response: nil exception: exception]; } - (bool)of_handleResponseBuffer: (unsigned char *)buffer length: (size_t)length sender: (const of_socket_address_t *)sender { OFDictionary *answerRecords = nil, *authorityRecords = nil; OFDictionary *additionalRecords = nil; OFDNSResponse *response = nil; id exception = nil; OFNumber *ID; OFDNSResolverContext *context; 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]]; context = [[[_queries objectForKey: ID] retain] autorelease]; if (context == nil) return true; if (context->_TCPSocket != nil) { if ([_TCPQueries objectForKey: context->_TCPSocket] != context) return true; } else if (!of_socket_address_equal(sender, &context->_usedNameServer)) return true; [context->_cancelTimer invalidate]; [context->_cancelTimer release]; context->_cancelTimer = nil; [_queries removeObjectForKey: ID]; |
︙ | ︙ | |||
899 900 901 902 903 904 905 | @throw [OFInvalidServerReplyException exception]; /* Opcode */ if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78)) @throw [OFInvalidServerReplyException exception]; /* TC */ | | > > > | > > > > > > > | 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 | @throw [OFInvalidServerReplyException exception]; /* Opcode */ if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78)) @throw [OFInvalidServerReplyException exception]; /* TC */ if (buffer[2] & 0x02) { of_run_loop_mode_t runLoopMode; if (context->_settings->_usesTCP) @throw [OFTruncatedDataException exception]; context->_settings->_usesTCP = true; runLoopMode = [OFRunLoop currentRunLoop].currentMode; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return false; } /* RCODE */ switch (buffer[3] & 0x0F) { case 0: break; case 1: error = OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT; |
︙ | ︙ | |||
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 | if ([context->_delegate respondsToSelector: @selector(resolver:didPerformQuery:response:exception:)]) [context->_delegate resolver: self didPerformQuery: context->_query response: response exception: exception]; return false; } - (void)asyncResolveAddressesForHost: (OFString *)host delegate: (id <OFDNSResolverHostDelegate>)delegate { [self asyncResolveAddressesForHost: host | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 | if ([context->_delegate respondsToSelector: @selector(resolver:didPerformQuery:response:exception:)]) [context->_delegate resolver: self didPerformQuery: context->_query response: response exception: exception]; return false; } - (bool)socket: (OFDatagramSocket *)sock didReceiveIntoBuffer: (void *)buffer length: (size_t)length sender: (const of_socket_address_t *)sender exception: (id)exception { if (exception != nil) return true; return [self of_handleResponseBuffer: buffer length: length sender: sender]; } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { OFDNSResolverContext *context = [_TCPQueries objectForKey: sock]; OF_ENSURE(context != nil); if (exception != nil) { /* * TODO: Handle error immediately instead of waiting for the * timer to try the next nameserver or to retry. */ [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; return; } if (context->_TCPQueryData == nil) { size_t queryDataCount = context->_queryData.count; uint16_t tmp; if (queryDataCount > UINT16_MAX) @throw [OFOutOfRangeException exception]; context->_TCPQueryData = [[OFMutableData alloc] initWithCapacity: queryDataCount + 2]; tmp = OF_BSWAP16_IF_LE(queryDataCount); [context->_TCPQueryData addItems: &tmp count: sizeof(tmp)]; [context->_TCPQueryData addItems: context->_queryData.items count: queryDataCount]; } [sock asyncWriteData: context->_TCPQueryData]; } - (OFData *)stream: (OFStream *)stream didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { OFTCPSocket *sock = (OFTCPSocket *)stream; OFDNSResolverContext *context = [_TCPQueries objectForKey: sock]; OF_ENSURE(context != nil); if (exception != nil) { /* * TODO: Handle error immediately instead of waiting for the * timer to try the next nameserver or to retry. */ [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; return nil; } if (context->_TCPBuffer == nil) context->_TCPBuffer = [context allocMemoryWithSize: MAX_DNS_RESPONSE_LENGTH]; [sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: 2]; return nil; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { OFTCPSocket *sock = (OFTCPSocket *)stream; OFDNSResolverContext *context = [_TCPQueries objectForKey: sock]; OF_ENSURE(context != nil); if (exception != nil) { /* * TODO: Handle error immediately instead of waiting for the * timer to try the next nameserver or to retry. */ goto done; } if (context->_responseLength == 0) { unsigned char *ucBuffer = buffer; OF_ENSURE(length == 2); context->_responseLength = (ucBuffer[0] << 8) | ucBuffer[1]; if (context->_responseLength > MAX_DNS_RESPONSE_LENGTH) @throw [OFOutOfRangeException exception]; if (context->_responseLength == 0) goto done; [sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: context->_responseLength]; return false; } if (length != context->_responseLength) /* * The connection was closed before we received the entire * response. */ goto done; [self of_handleResponseBuffer: buffer length: length sender: NULL]; done: [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; return false; } - (void)asyncResolveAddressesForHost: (OFString *)host delegate: (id <OFDNSResolverHostDelegate>)delegate { [self asyncResolveAddressesForHost: host |
︙ | ︙ |
Modified src/OFDNSResolverSettings.m from [67fa5dd9c3] to [995314850c].
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #ifdef OF_WINDOWS # define interface struct # include <iphlpapi.h> # undef interface #endif #ifdef OF_NINTENDO_3DS # include <3ds.h> #endif #import "socket_helpers.h" #if defined(OF_HAIKU) # define HOSTS_PATH @"/system/settings/network/hosts" # define RESOLV_CONF_PATH @"/system/settings/network/resolv.conf" | > > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #ifdef OF_WINDOWS # define interface struct # include <iphlpapi.h> # undef interface #endif #ifdef OF_NINTENDO_3DS /* Newer versions of libctru started using id as a parameter name. */ # define id id_3ds # include <3ds.h> # undef id #endif #import "socket_helpers.h" #if defined(OF_HAIKU) # define HOSTS_PATH @"/system/settings/network/hosts" # define RESOLV_CONF_PATH @"/system/settings/network/resolv.conf" |
︙ | ︙ | |||
481 482 483 484 485 486 487 | pool = objc_autoreleasePoolPush(); [self setDefaults]; #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES | | < | | > > | > | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | pool = objc_autoreleasePoolPush(); [self setDefaults]; #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES OFWindowsRegistryKey *key = [[OFWindowsRegistryKey localMachineKey] openSubkeyAtPath: @"SYSTEM\\CurrentControlSet\\Services\\" @"Tcpip\\Parameters" securityAndAccessRights: KEY_QUERY_VALUE]; path = [[[key stringForValue: @"DataBasePath"] stringByAppendingPathComponent: @"hosts"] stringByExpandingWindowsEnvironmentStrings]; if (path != nil) [self parseHosts: path]; # endif [self obtainWindowsSystemConfig]; #elif defined(OF_AMIGAOS4) |
︙ | ︙ |
Modified src/OFDNSResourceRecord.h from [eacf6b96e8] to [279eea4da6].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @file */ @class OFData; /*! * @brief The DNS class. */ typedef enum { /*! IN */ | > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @file */ @class OFArray OF_GENERIC(ObjectType); @class OFData; /*! * @brief The DNS class. */ typedef enum { /*! IN */ |
︙ | ︙ | |||
586 587 588 589 590 591 592 | * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a TXT DNS resource record. */ OF_SUBCLASSING_RESTRICTED @interface OFTXTDNSResourceRecord: OFDNSResourceRecord { | | | | | | 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a TXT DNS resource record. */ OF_SUBCLASSING_RESTRICTED @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 * @param textStrings An array of text strings for the resource record * @param TTL The time to live for the resource record * @return An initialized OFTXTDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass textStrings: (OFArray OF_GENERIC(OFData *) *)textStrings TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end #ifdef __cplusplus extern "C" { #endif extern OFString *_Nonnull of_dns_class_to_string(of_dns_class_t DNSClass); |
︙ | ︙ |
Modified src/OFDNSResourceRecord.m from [95ccb6d631] to [054747ac72].
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFDNSResourceRecord.h" #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" OFString * of_dns_class_to_string(of_dns_class_t DNSClass) | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFDNSResourceRecord.h" #import "OFArray.h" #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" OFString * of_dns_class_to_string(of_dns_class_t DNSClass) |
︙ | ︙ | |||
76 77 78 79 80 81 82 | string = string.uppercaseString; if ([string isEqual: @"IN"]) DNSClass = OF_DNS_CLASS_IN; else { @try { | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | string = string.uppercaseString; if ([string isEqual: @"IN"]) DNSClass = OF_DNS_CLASS_IN; else { @try { DNSClass = (of_dns_class_t)string.decimalValue; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidArgumentException exception]; } } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
116 117 118 119 120 121 122 123 124 125 | recordType = OF_DNS_RECORD_TYPE_TXT; else if ([string isEqual: @"RP"]) recordType = OF_DNS_RECORD_TYPE_RP; else if ([string isEqual: @"AAAA"]) recordType = OF_DNS_RECORD_TYPE_AAAA; else if ([string isEqual: @"SRV"]) recordType = OF_DNS_RECORD_TYPE_SRV; else { @try { recordType = | > > | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | recordType = OF_DNS_RECORD_TYPE_TXT; else if ([string isEqual: @"RP"]) recordType = OF_DNS_RECORD_TYPE_RP; else if ([string isEqual: @"AAAA"]) recordType = OF_DNS_RECORD_TYPE_AAAA; else if ([string isEqual: @"SRV"]) 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; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidArgumentException exception]; } } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
1246 1247 1248 1249 1250 1251 1252 | @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, _priority, _weight, _target, _port, _TTL]; } @end @implementation OFTXTDNSResourceRecord | | | | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, _priority, _weight, _target, _port, _TTL]; } @end @implementation OFTXTDNSResourceRecord @synthesize textStrings = _textStrings; - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass recordType: (of_dns_record_type_t)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (of_dns_class_t)DNSClass textStrings: (OFArray OF_GENERIC(OFData *) *)textStrings TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OF_DNS_RECORD_TYPE_TXT TTL: TTL]; @try { _textStrings = [textStrings copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_textStrings release]; [super dealloc]; } - (bool)isEqual: (id)object { OFTXTDNSResourceRecord *record; |
︙ | ︙ | |||
1304 1305 1306 1307 1308 1309 1310 | if (record->_DNSClass != _DNSClass) return false; if (record->_recordType != _recordType) return false; | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > > > > > > | 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 | if (record->_DNSClass != _DNSClass) return false; if (record->_recordType != _recordType) return false; if (record->_textStrings != _textStrings && ![record->_textStrings isEqual: _textStrings]) return false; return true; } - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _DNSClass >> 8); OF_HASH_ADD(hash, _DNSClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _textStrings.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFMutableString *text = [OFMutableString string]; bool first = true; OFString *ret; for (OFData *string in _textStrings) { const unsigned char *stringItems = string.items; size_t stringCount = string.count; if (first) { first = false; [text appendString: @"\""]; } else [text appendString: @" \""]; for (size_t i = 0; i < stringCount; i++) { if (stringItems[i] == '\\') [text appendString: @"\\\\"]; else if (stringItems[i] == '"') [text appendString: @"\\\""]; else if (stringItems[i] < 0x20) [text appendFormat: @"\\x%02X", stringItems[i]]; else if (stringItems[i] < 0x7F) [text appendFormat: @"%c", stringItems[i]]; else [text appendFormat: @"\\x%02X", stringItems[i]]; } [text appendString: @"\""]; } ret = [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tText strings = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_class_to_string(_DNSClass), text, _TTL]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFDNSResponse.h from [156cc97081] to [12af35aca6].
︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) of_dns_response_records_t additionalRecords; /*! * @brief Creates a new, autoreleased OFDNSResponse. * * @param answerRecords The answer records of the response * @param authorityRecords The authority records of the response * @param additionalRecords The additional records of the response * @return A new, autoreleased OFDNSResponse */ + (instancetype) 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 answerRecords The answer records of the response * @param authorityRecords The authority records of the response * @param additionalRecords The additional records of the response * @return An initialized OFDNSResponse */ - (instancetype) initWithDomainName: (OFString *)domainName | > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | * 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 * @param additionalRecords The additional records of the response * @return A new, autoreleased OFDNSResponse */ + (instancetype) 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 * @param additionalRecords The additional records of the response * @return An initialized OFDNSResponse */ - (instancetype) initWithDomainName: (OFString *)domainName |
︙ | ︙ |
Modified src/OFData+MessagePackValue.m from [95748cc907] to [caaaf51219].
︙ | ︙ | |||
276 277 278 279 280 281 282 | if (length < 9) @throw [OFTruncatedDataException exception]; *object = [OFNumber numberWithInt64: readUInt64(buffer + 1)]; return 9; /* Floating point */ case 0xCA:; /* float 32 */ | < < | < | | < < | < | | < | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | 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: |
︙ | ︙ |
Added src/OFDatagramSocket.h version [cb9e65f15c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFKernelEventObserver.h" #import "OFRunLoop.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @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 * success * @return A bool whether the same block should be used for the next receive */ 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 * success * @return The data to repeat the send with or nil if it should not repeat */ 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 <OFObject> @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 * @param sender The address of the sender of the packet * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (bool)socket: (OFDatagramSocket *)socket 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 * @param exception An exception that occurred while sending, or nil on success * @return The data to repeat the send with or nil if it should not repeat */ - (nullable OFData *)socket: (OFDatagramSocket *)socket 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* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFDatagramSocket: OFObject <OFCopying, OFReadyForReadingObserving, OFReadyForWritingObserving> { of_socket_t _socket; bool _canBlock; #ifdef OF_WII bool _canSendToBroadcastAddresses; #endif id <OFDatagramSocketDelegate> _Nullable _delegate; OF_RESERVE_IVARS(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 <OFDatagramSocketDelegate> 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 * @param length The length of the buffer * @param sender A pointer to an @ref of_socket_address_t, which will be set to * the address of the sender * @return The length of the received datagram */ - (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. * * @param buffer The buffer to write the datagram to * @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. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive */ - (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. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param block The block to call when the datagram has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more datagrams have been * received. If you want the next method in the queue to handle * the datagram received next, you need to return false from the * method. */ - (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. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive * @param block The block to call when the datagram has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more datagrams have been * received. If you want the next method in the queue to handle * the datagram received next, you need to return false from the * method. */ - (void)asyncReceiveIntoBuffer: (void *)buffer 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 * datagram should be sent */ - (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. * @param runLoopMode The run loop mode in which to perform the async send */ - (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. * @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 * if it should not repeat. */ - (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. * @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 * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data 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 |
Added src/OFDatagramSocket.m version [3479c8733b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFDatagramSocket.h" #import "OFData.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #import "OFGetOptionFailedException.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" #import "socket.h" #import "socket_helpers.h" @implementation OFDatagramSocket @synthesize delegate = _delegate; + (void)initialize { if (self != [OFDatagramSocket class]) return; if (!of_socket_init()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; @try { if (self.class == [OFDatagramSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _socket = INVALID_SOCKET; _canBlock = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket != INVALID_SOCKET) [self close]; [super dealloc]; } - (id)copy { return [self retain]; } - (bool)canBlock { return _canBlock; } - (void)setCanBlock: (bool)canBlock { #if defined(HAVE_FCNTL) int flags = fcntl(_socket, F_GETFL, 0); if (flags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; if (canBlock) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(_socket, F_SETFL, flags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; _canBlock = canBlock; #elif defined(OF_WINDOWS) u_long v = canBlock; if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; _canBlock = canBlock; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)setCanSendToBroadcastAddresses: (bool)canSendToBroadcastAddresses { int v = canSendToBroadcastAddresses; if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; #ifdef OF_WII _canSendToBroadcastAddresses = canSendToBroadcastAddresses; #endif } - (bool)canSendToBroadcastAddresses { #ifndef OF_WII int v; socklen_t len = sizeof(v); if (getsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; return v; #else return _canSendToBroadcastAddresses; #endif } - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length sender: (of_socket_address_t *)sender { ssize_t ret; if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; sender->length = (socklen_t)sizeof(sender->sockaddr); #ifndef OF_WINDOWS if ((ret = recvfrom(_socket, buffer, length, 0, &sender->sockaddr.sockaddr, &sender->length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recvfrom(_socket, buffer, (int)length, 0, &sender->sockaddr.sockaddr, &sender->length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #endif switch (sender->sockaddr.sockaddr.sa_family) { case AF_INET: sender->family = OF_SOCKET_ADDRESS_FAMILY_IPV4; break; #ifdef OF_HAVE_IPV6 case AF_INET6: sender->family = OF_SOCKET_ADDRESS_FAMILY_IPV6; break; #endif #ifdef OF_HAVE_IPX case AF_IPX: sender->family = OF_SOCKET_ADDRESS_FAMILY_IPX; break; #endif default: sender->family = OF_SOCKET_ADDRESS_FAMILY_UNKNOWN; break; } return ret; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: of_run_loop_mode_default]; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncReceiveForDatagramSocket: self buffer: buffer length: length mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (of_datagram_socket_async_receive_block_t)block { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_datagram_socket_async_receive_block_t)block { [OFRunLoop of_addAsyncReceiveForDatagramSocket: self buffer: buffer length: length mode: runLoopMode block: block delegate: nil]; } #endif - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_socket_address_t *)receiver { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS ssize_t bytesWritten; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = sendto(_socket, (void *)buffer, length, 0, (struct sockaddr *)&receiver->sockaddr.sockaddr, receiver->length)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: of_socket_errno()]; #else int bytesWritten; if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = sendto(_socket, buffer, (int)length, 0, &receiver->sockaddr.sockaddr, receiver->length)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: of_socket_errno()]; #endif if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver { [self asyncSendData: data receiver: receiver runLoopMode: of_run_loop_mode_default]; } - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncSendForDatagramSocket: self data: data receiver: receiver mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver block: (of_datagram_socket_async_send_data_block_t)block { [self asyncSendData: data receiver: receiver runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_datagram_socket_async_send_data_block_t)block { [OFRunLoop of_addAsyncSendForDatagramSocket: self data: data receiver: receiver mode: runLoopMode block: block delegate: nil]; } #endif - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self mode: of_run_loop_mode_default]; } - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket; #else if (_socket == INVALID_SOCKET) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (int)fileDescriptorForWriting { #ifndef OF_WINDOWS return _socket; #else if (_socket == INVALID_SOCKET) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (void)close { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; closesocket(_socket); _socket = INVALID_SOCKET; } @end |
Modified src/OFDate.m from [ab9874f31d] to [1c4647d564].
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # define trunc(x) ((int64_t)(x)) #endif #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) static OFMutex *mutex; #endif #ifdef HAVE_GMTIME_R # define GMTIME_RET(field) \ time_t seconds = (time_t)_seconds; \ struct tm tm; \ \ if (seconds != trunc(_seconds)) \ | > > > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # define trunc(x) ((int64_t)(x)) #endif #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) static OFMutex *mutex; #endif #ifdef OF_WINDOWS static __time64_t (*func__mktime64)(struct tm *); #endif #ifdef HAVE_GMTIME_R # define GMTIME_RET(field) \ time_t seconds = (time_t)_seconds; \ struct tm tm; \ \ if (seconds != trunc(_seconds)) \ |
︙ | ︙ | |||
182 183 184 185 186 187 188 | /* Time zone */ seconds += -(double)*tz * 60; return seconds; } @implementation OFDate | < < > > > > | > > > > | > | > > > > > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | /* Time zone */ seconds += -(double)*tz * 60; return seconds; } @implementation OFDate + (void)initialize { #ifdef OF_WINDOWS HMODULE module; #endif if (self != [OFDate class]) return; #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) mutex = [[OFMutex alloc] init]; #endif #ifdef OF_WINDOWS if ((module = LoadLibrary("msvcrt.dll")) != NULL) func__mktime64 = (__time64_t (*)(struct tm *)) GetProcAddress(module, "_mktime64"); #endif } + (instancetype)date { return [[[self alloc] init] autorelease]; } + (instancetype)dateWithTimeIntervalSince1970: (of_time_interval_t)seconds |
︙ | ︙ | |||
313 314 315 316 317 318 319 | tm.tm_isdst = -1; if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; if (tz == INT16_MAX) { | | > | | > | > | | > > > < < < < < < | > | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | 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; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![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))); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
379 380 381 382 383 384 385 | return true; } - (uint32_t)hash { uint32_t hash; | < | < < | | | | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | return true; } - (uint32_t)hash { uint32_t hash; double tmp; OF_HASH_INIT(hash); tmp = OF_BSWAP_DOUBLE_IF_BE(_seconds); for (size_t i = 0; i < sizeof(double); i++) OF_HASH_ADD(hash, ((char *)&tmp)[i]); OF_HASH_FINALIZE(hash); return hash; } - (id)copy |
︙ | ︙ | |||
427 428 429 430 431 432 433 | return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; | < < < < < | | > | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className 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)))]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } |
︙ | ︙ |
Modified src/OFFile.m from [1f08d5d8ea] to [14d95d3e71].
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #import "OFFile.h" #import "OFLocale.h" #import "OFString.h" #import "OFURL.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" | > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #import "OFFile.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFURL.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" |
︙ | ︙ | |||
216 217 218 219 220 221 222 | #ifndef OF_AMIGAOS if ((flags = parseMode(mode.UTF8String)) == -1) @throw [OFInvalidArgumentException exception]; flags |= O_BINARY | O_CLOEXEC; | | > | | > > | > | | > | | > > | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | #ifndef OF_AMIGAOS if ((flags = parseMode(mode.UTF8String)) == -1) @throw [OFInvalidArgumentException exception]; flags |= O_BINARY | O_CLOEXEC; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) handle = _wopen(path.UTF16String, flags, _S_IREAD | _S_IWRITE); else # endif # ifdef HAVE_OPEN64 handle = open64( [path cStringWithEncoding: [OFLocale encoding]], flags, 0666); # else handle = open( [path cStringWithEncoding: [OFLocale encoding]], flags, 0666); # endif if (handle == -1) @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: errno]; #else if ((handle = malloc(sizeof(*handle))) == NULL) @throw [OFOutOfMemoryException |
︙ | ︙ |
Modified src/OFFileManager.h from [3b9bb8eaec] to [832085a76a].
︙ | ︙ | |||
138 139 140 141 142 143 144 | * * 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; /*! | | | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | * * 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; /*! |
︙ | ︙ | |||
186 187 188 189 190 191 192 | * * 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; /*! | | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | * * 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; |
︙ | ︙ |
Modified src/OFFileManager.m from [6f997251ad] to [c5306f3b5d].
︙ | ︙ | |||
160 161 162 163 164 165 166 | } #ifdef OF_HAVE_FILES - (OFString *)currentDirectoryPath { # if defined(OF_WINDOWS) OFString *ret; | > > | | | | | > > > > > > > > > > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | } #ifdef OF_HAVE_FILES - (OFString *)currentDirectoryPath { # if defined(OF_WINDOWS) OFString *ret; if ([OFSystemInfo isWindowsNT]) { wchar_t *buffer = _wgetcwd(NULL, 0); @try { ret = [OFString stringWithUTF16String: buffer]; } @finally { free(buffer); } } else { char *buffer = _getcwd(NULL, 0); @try { ret = [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; } @finally { free(buffer); } } return ret; # elif defined(OF_AMIGAOS) char buffer[512]; if (!NameFromLock(((struct Process *)FindTask(NULL))->pr_CurrentDir, |
︙ | ︙ | |||
478 479 480 481 482 483 484 | } - (void)changeCurrentDirectoryPath: (OFString *)path { if (path == nil) @throw [OFInvalidArgumentException exception]; | < < < < < | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | } - (void)changeCurrentDirectoryPath: (OFString *)path { if (path == nil) @throw [OFInvalidArgumentException exception]; # ifdef OF_AMIGAOS BPTR lock, oldLock; if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]], SHARED_LOCK)) == 0) { int errNo; switch (IoErr()) { |
︙ | ︙ | |||
517 518 519 520 521 522 523 | if (!dirChanged) originalDirLock = oldLock; else UnLock(oldLock); dirChanged = true; # else | > > > > > > > > | > > | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | if (!dirChanged) originalDirLock = oldLock; else UnLock(oldLock); dirChanged = true; # else int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wchdir(path.UTF16String); else # endif status = chdir( [path cStringWithEncoding: [OFLocale encoding]]); if (status != 0) @throw [OFChangeCurrentDirectoryPathFailedException exceptionWithPath: path errNo: errno]; # endif } - (void)changeCurrentDirectoryURL: (OFURL *)URL |
︙ | ︙ |
Modified src/OFFileURLHandler.m from [f538dd0518] to [b6ef19d4e0].
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #import "OFFileURLHandler.h" #import "OFArray.h" #import "OFDate.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFURL.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFCreateDirectoryFailedException.h" | > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #import "OFFileURLHandler.h" #import "OFArray.h" #import "OFDate.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFSystemInfo.h" #import "OFURL.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFCreateDirectoryFailedException.h" |
︙ | ︙ | |||
105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #endif #if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) && !defined(OF_WINDOWS) static OFMutex *readdirMutex; #endif #ifdef OF_WINDOWS static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD); #endif #ifdef OF_WINDOWS static of_time_interval_t filetimeToTimeInterval(const FILETIME *filetime) { return (double)((int64_t)filetime->dwHighDateTime << 32 | | > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | #endif #if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) && !defined(OF_WINDOWS) static OFMutex *readdirMutex; #endif #ifdef OF_WINDOWS static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD); static WINAPI BOOLEAN (*func_CreateHardLinkW)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); #endif #ifdef OF_WINDOWS static of_time_interval_t filetimeToTimeInterval(const FILETIME *filetime) { return (double)((int64_t)filetime->dwHighDateTime << 32 | |
︙ | ︙ | |||
144 145 146 147 148 149 150 151 | #endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) WIN32_FILE_ATTRIBUTE_DATA data; | > > | > > > > > | > > > > > | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) WIN32_FILE_ATTRIBUTE_DATA data; bool success; if ([OFSystemInfo isWindowsNT]) success = GetFileAttributesExW(path.UTF16String, GetFileExInfoStandard, &data); else success = GetFileAttributesExA( [path cStringWithEncoding: [OFLocale encoding]], GetFileExInfoStandard, &data); if (!success) { setErrno(); return -1; } buffer->st_size = (uint64_t)data.nFileSizeHigh << 32 | data.nFileSizeLow; if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) buffer->st_mode = S_IFDIR; else if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { /* * No need to use A functions in this branch: This is only * available on NTFS (and hence Windows NT) anyway. */ WIN32_FIND_DATAW findData; HANDLE findHandle; if ((findHandle = FindFirstFileW(path.UTF16String, &findData)) == INVALID_HANDLE_VALUE) { setErrno(); return -1; |
︙ | ︙ | |||
494 495 496 497 498 499 500 | passwdMutex = [[OFMutex alloc] init]; #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) readdirMutex = [[OFMutex alloc] init]; #endif #ifdef OF_WINDOWS | | > > > > > | 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | passwdMutex = [[OFMutex alloc] init]; #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) readdirMutex = [[OFMutex alloc] init]; #endif #ifdef OF_WINDOWS if ((module = LoadLibrary("kernel32.dll")) != NULL) { func_CreateSymbolicLinkW = (WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD)) GetProcAddress(module, "CreateSymbolicLinkW"); func_CreateHardLinkW = (WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES)) GetProcAddress(module, "CreateHardLinkW"); } #endif /* * Make sure OFFile is initialized. * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; |
︙ | ︙ | |||
581 582 583 584 585 586 587 588 | - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL attributes: (of_file_attributes_t)attributes { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS uint16_t mode = permissions.uInt16Value & 0777; OFString *path = URL.fileSystemRepresentation; | > | > | | < > > > > | 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL attributes: (of_file_attributes_t)attributes { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS uint16_t mode = permissions.uInt16Value & 0777; OFString *path = URL.fileSystemRepresentation; int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wchmod(path.UTF16String, mode); else # endif status = chmod( [path cStringWithEncoding: [OFLocale encoding]], mode); if (status != 0) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: of_file_attribute_key_posix_permissions errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR |
︙ | ︙ | |||
769 770 771 772 773 774 775 | if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) | > > > | > > > > > | 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) int status; if ([OFSystemInfo isWindowsNT]) status = _wmkdir(path.UTF16String); else status = _mkdir( [path cStringWithEncoding: [OFLocale encoding]]); if (status != 0) @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock; if ((lock = CreateDir( |
︙ | ︙ | |||
835 836 837 838 839 840 841 | if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) HANDLE handle; | < > > > | | | | | | > | | | | | | | | | | | | | | | | | | | > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 | if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) HANDLE handle; path = [path stringByAppendingString: @"\\*"]; if ([OFSystemInfo isWindowsNT]) { WIN32_FIND_DATAW fd; if ((handle = FindFirstFileW(path.UTF16String, &fd)) == INVALID_HANDLE_VALUE) { int errNo = 0; if (GetLastError() == ERROR_FILE_NOT_FOUND) errNo = ENOENT; @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: errNo]; } @try { do { OFString *file; if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0) continue; file = [[OFString alloc] initWithUTF16String: fd.cFileName]; @try { [files addObject: file]; } @finally { [file release]; } } while (FindNextFileW(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: EIO]; } @finally { FindClose(handle); } } else { of_string_encoding_t encoding = [OFLocale encoding]; WIN32_FIND_DATA fd; if ((handle = FindFirstFileA( [path cStringWithEncoding: encoding], &fd)) == INVALID_HANDLE_VALUE) { int errNo = 0; if (GetLastError() == ERROR_FILE_NOT_FOUND) errNo = ENOENT; @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: errNo]; } @try { do { OFString *file; if (strcmp(fd.cFileName, ".") == 0 || strcmp(fd.cFileName, "..") == 0) continue; file = [[OFString alloc] initWithCString: fd.cFileName encoding: encoding]; @try { [files addObject: file]; } @finally { [file release]; } } while (FindNextFileA(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: EIO]; } @finally { FindClose(handle); } } #elif defined(OF_AMIGAOS) of_string_encoding_t encoding = [OFLocale encoding]; BPTR lock; if ((lock = Lock([path cStringWithEncoding: encoding], SHARED_LOCK)) == 0) { |
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 | [self removeItemAtURL: [OFURL fileURLWithPath: [path stringByAppendingPathComponent: item]]]; objc_autoreleasePoolPop(pool2); } #ifndef OF_AMIGAOS | > > | > | | < > > > > > > | | | | < > > > > | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 | [self removeItemAtURL: [OFURL fileURLWithPath: [path stringByAppendingPathComponent: item]]]; objc_autoreleasePoolPop(pool2); } #ifndef OF_AMIGAOS int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wrmdir(path.UTF16String); else # endif status = rmdir( [path cStringWithEncoding: [OFLocale encoding]]); if (status != 0) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; } else { int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wunlink(path.UTF16String); else # endif status = unlink( [path cStringWithEncoding: [OFLocale encoding]]); if (status != 0) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; #endif } #ifdef OF_AMIGAOS |
︙ | ︙ | |||
1162 1163 1164 1165 1166 1167 1168 | if (link([sourcePath cStringWithEncoding: encoding], [destinationPath cStringWithEncoding: encoding]) != 0) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; # else | > > > > | | 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 | if (link([sourcePath cStringWithEncoding: encoding], [destinationPath cStringWithEncoding: encoding]) != 0) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; # else if (func_CreateHardLinkW == NULL) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (!func_CreateHardLinkW(destinationPath.UTF16String, sourcePath.UTF16String, NULL)) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: 0]; # endif |
︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 | @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; pool = objc_autoreleasePoolPush(); | < < < < < < < | | 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; pool = objc_autoreleasePoolPush(); #ifdef OF_AMIGAOS of_string_encoding_t encoding = [OFLocale encoding]; if (!Rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding])) { int errNo; |
︙ | ︙ | |||
1275 1276 1277 1278 1279 1280 1281 | @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errNo]; } #else | > > > > > > > > | | | | | > > > > > | 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 | @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errNo]; } #else int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wrename(source.fileSystemRepresentation.UTF16String, destination.fileSystemRepresentation.UTF16String); else { # endif of_string_encoding_t encoding = [OFLocale encoding]; status = rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding]); # ifdef OF_WINDOWS } # endif if (status != 0) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; #endif objc_autoreleasePoolPop(pool); return true; } @end |
Modified src/OFHTTPClient.h from [1c7acee4b8] to [a28aee5e52].
︙ | ︙ | |||
143 144 145 146 147 148 149 | OF_SUBCLASSING_RESTRICTED @interface OFHTTPClient: OFObject { #ifdef OF_HTTPCLIENT_M @public #endif OFObject <OFHTTPClientDelegate> *_Nullable _delegate; | | | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | OF_SUBCLASSING_RESTRICTED @interface OFHTTPClient: OFObject { #ifdef OF_HTTPCLIENT_M @public #endif OFObject <OFHTTPClientDelegate> *_Nullable _delegate; bool _allowsInsecureRedirects, _inProgress; OFTCPSocket *_Nullable _socket; OFURL *_Nullable _lastURL; bool _lastWasHEAD; OFHTTPResponse *_Nullable _lastResponse; } /*! * @brief The delegate of the HTTP request. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) OFObject <OFHTTPClientDelegate> *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; |
︙ | ︙ |
Modified src/OFHTTPClient.m from [36ad6829ee] to [7d20d55912].
︙ | ︙ | |||
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | - (void)closeAndReconnect; @end @interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving> { OFHTTPClientRequestHandler *_handler; OFTCPSocket *_socket; uintmax_t _toWrite; bool _atEndOfStream; } - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler socket: (OFTCPSocket *)sock; @end @interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving> { OFTCPSocket *_socket; | > | > | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | - (void)closeAndReconnect; @end @interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving> { OFHTTPClientRequestHandler *_handler; OFTCPSocket *_socket; bool _chunked; uintmax_t _toWrite; bool _atEndOfStream; } - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler socket: (OFTCPSocket *)sock; @end @interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving> { OFTCPSocket *_socket; bool _hasContentLength, _chunked, _keepAlive; bool _atEndOfStream, _setAtEndOfStream; intmax_t _toRead; } @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock; @end |
︙ | ︙ | |||
114 115 116 117 118 119 120 121 122 123 124 125 126 127 | void *pool = objc_autoreleasePoolPush(); of_http_request_method_t method = request.method; OFURL *URL = request.URL; OFString *path; OFString *user = URL.user, *password = URL.password; OFMutableString *requestString; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator OF_GENERIC(OFString *) *keyEnumerator, *objectEnumerator; OFString *key, *object; if (URL.path != nil) path = URL.URLEncodedPath; else path = @"/"; | > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | void *pool = objc_autoreleasePoolPush(); of_http_request_method_t method = request.method; OFURL *URL = request.URL; OFString *path; OFString *user = URL.user, *password = URL.password; OFMutableString *requestString; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; bool hasContentLength, chunked; OFEnumerator OF_GENERIC(OFString *) *keyEnumerator, *objectEnumerator; OFString *key, *object; if (URL.path != nil) path = URL.URLEncodedPath; else path = @"/"; |
︙ | ︙ | |||
181 182 183 184 185 186 187 | if (request.protocolVersion.major == 1 && request.protocolVersion.minor == 0 && [headers objectForKey: @"Connection"] == nil) [headers setObject: @"keep-alive" forKey: @"Connection"]; | | > > > > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | if (request.protocolVersion.major == 1 && request.protocolVersion.minor == 0 && [headers objectForKey: @"Connection"] == nil) [headers setObject: @"keep-alive" forKey: @"Connection"]; hasContentLength = ([headers objectForKey: @"Content-Length"] != nil); chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; if ((hasContentLength || chunked) && [headers objectForKey: @"Content-Type"] == nil) [headers setObject: @"application/x-www-form-" @"urlencoded; charset=UTF-8" forKey: @"Content-Type"]; keyEnumerator = [headers keyEnumerator]; objectEnumerator = [headers objectEnumerator]; |
︙ | ︙ | |||
304 305 306 307 308 309 310 | response.protocolVersionString = _version; response.statusCode = _status; response.headers = _serverHeaders; connectionHeader = [_serverHeaders objectForKey: @"Connection"]; if ([_version isEqual: @"1.1"]) { if (connectionHeader != nil) | | < < | | < < < > > > > > > > > > > > > > > > | | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | response.protocolVersionString = _version; response.statusCode = _status; response.headers = _serverHeaders; connectionHeader = [_serverHeaders objectForKey: @"Connection"]; if ([_version isEqual: @"1.1"]) { if (connectionHeader != nil) keepAlive = [connectionHeader isEqual: @"close"]; else keepAlive = true; } else { if (connectionHeader != nil) keepAlive = ([connectionHeader caseInsensitiveCompare: @"keep-alive"] == OF_ORDERED_SAME); else keepAlive = false; } if (keepAlive) { response.of_keepAlive = true; _client->_socket = [sock retain]; _client->_lastURL = [URL copy]; _client->_lastWasHEAD = (_request.method == OF_HTTP_REQUEST_METHOD_HEAD); _client->_lastResponse = [response retain]; } if (_redirects > 0 && (_status == 301 || _status == 302 || _status == 303 || _status == 307) && (location = [_serverHeaders objectForKey: @"Location"]) != nil) { bool follow = true; OFURL *newURL; OFString *newURLScheme; newURL = [OFURL URLWithString: location relativeToURL: URL]; newURLScheme = newURL.scheme; if ([newURLScheme caseInsensitiveCompare: @"http"] != OF_ORDERED_SAME && [newURLScheme caseInsensitiveCompare: @"https"] != OF_ORDERED_SAME) follow = false; if (!_client->_allowsInsecureRedirects && [URL.scheme caseInsensitiveCompare: @"https"] == OF_ORDERED_SAME && [newURLScheme caseInsensitiveCompare: @"http"] == OF_ORDERED_SAME) follow = false; if (follow && [_client->_delegate respondsToSelector: @selector( client:shouldFollowRedirect:statusCode:request:response:)]) follow = [_client->_delegate client: _client shouldFollowRedirect: newURL statusCode: _status request: _request response: response]; else if (follow) follow = defaultShouldFollow(_request.method, _status); if (follow) { OFDictionary OF_GENERIC(OFString *, OFString *) *headers = _request.headers; OFHTTPRequest *newRequest = [[_request copy] autorelease]; |
︙ | ︙ | |||
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | - (OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding bytesWritten: (size_t)bytesWritten exception: (id)exception { if (exception != nil) { if ([exception isKindOfClass: [OFWriteFailedException class]] && ([exception errNo] == ECONNRESET || [exception errNo] == EPIPE)) { /* In case a keep-alive connection timed out */ [self closeAndReconnect]; return nil; } [self raiseException: exception]; return nil; } _firstLine = true; | > > > > > > > | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | - (OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding bytesWritten: (size_t)bytesWritten exception: (id)exception { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; bool chunked; if (exception != nil) { if ([exception isKindOfClass: [OFWriteFailedException class]] && ([exception errNo] == ECONNRESET || [exception errNo] == EPIPE)) { /* In case a keep-alive connection timed out */ [self closeAndReconnect]; return nil; } [self raiseException: exception]; return nil; } _firstLine = true; headers = _request.headers; chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; if (chunked || [headers objectForKey: @"Content-Length"] != nil) { stream.delegate = nil; OFStream *requestBody = [[[OFHTTPClientRequestBodyStream alloc] initWithHandler: self socket: (OFTCPSocket *)stream] autorelease]; if ([_client->_delegate respondsToSelector: |
︙ | ︙ | |||
666 667 668 669 670 671 672 | OFURL *URL = _request.URL; OFTCPSocket *sock; uint16_t port; OFNumber *URLPort; [_client close]; | | > | 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 | OFURL *URL = _request.URL; OFTCPSocket *sock; uint16_t port; OFNumber *URLPort; [_client close]; if ([URL.scheme caseInsensitiveCompare: @"https"] == OF_ORDERED_SAME) { if (of_tls_socket_class == Nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; sock = [[[of_tls_socket_class alloc] init] autorelease]; port = 443; } else { |
︙ | ︙ | |||
700 701 702 703 704 705 706 | socket: (OFTCPSocket *)sock { self = [super init]; @try { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; intmax_t contentLength; | | > > > | > | > | | | | | < | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | socket: (OFTCPSocket *)sock { self = [super init]; @try { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; intmax_t contentLength; OFString *transferEncoding, *contentLengthString; _handler = [handler retain]; _socket = [sock retain]; headers = _handler->_request.headers; transferEncoding = [headers objectForKey: @"Transfer-Encoding"]; _chunked = [transferEncoding isEqual: @"chunked"]; contentLengthString = [headers objectForKey: @"Content-Length"]; if (contentLengthString != nil) { if (_chunked || contentLengthString.length == 0) @throw [OFInvalidArgumentException exception]; contentLength = contentLengthString.decimalValue; if (contentLength < 0) @throw [OFOutOfRangeException exception]; _toWrite = contentLength; } else if (!_chunked) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; } return self; |
︙ | ︙ | |||
746 747 748 749 750 751 752 753 754 755 756 757 758 759 | { size_t requestedLength = length; size_t ret; if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: requestedLength bytesWritten: 0 errNo: 0]; | > > > > > > > > > > | > > > | | | > | 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 | { size_t requestedLength = length; size_t ret; if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; /* * We must not send a chunk of size 0, as that would end the body. We * always ignore writing 0 bytes to still allow writing 0 bytes after * the end of stream. */ if (length == 0) return 0; if (_atEndOfStream) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: requestedLength bytesWritten: 0 errNo: 0]; if (_chunked) [_socket writeFormat: @"%zX\r\n", length]; else if (length > _toWrite) length = (size_t)_toWrite; ret = [_socket writeBuffer: buffer length: length]; if (_chunked) [_socket writeString: @"\r\n"]; if (ret > length) @throw [OFOutOfRangeException exception]; if (!_chunked) { _toWrite -= ret; if (_toWrite == 0) _atEndOfStream = true; } if (requestedLength > length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: requestedLength bytesWritten: ret errNo: 0]; |
︙ | ︙ | |||
787 788 789 790 791 792 793 | } - (void)close { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; | > > | | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 | } - (void)close { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_chunked) [_socket writeString: @"0\r\n\r\n"]; else if (_toWrite > 0) @throw [OFTruncatedDataException exception]; _socket.delegate = _handler; [_socket asyncReadLine]; [_socket release]; _socket = nil; |
︙ | ︙ | |||
836 837 838 839 840 841 842 843 844 845 | super.headers = headers; _chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; contentLength = [headers objectForKey: @"Content-Length"]; if (contentLength != nil) { _hasContentLength = true; @try { | > > > | | < < | 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 | super.headers = headers; _chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; contentLength = [headers objectForKey: @"Content-Length"]; if (contentLength != nil) { if (_chunked || contentLength.length == 0) @throw [OFInvalidServerReplyException exception]; _hasContentLength = true; @try { _toRead = contentLength.decimalValue; if (_toRead < 0) @throw [OFInvalidServerReplyException exception]; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } } } - (size_t)lowlevelReadIntoBuffer: (void *)buffer |
︙ | ︙ | |||
872 873 874 875 876 877 878 | if (_socket.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ if (!_chunked) { size_t ret; | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < | > > > > > > > > > > > > > > > > | < < < < | | < < < < < < < < < < < < | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | if (_socket.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ if (!_chunked) { size_t ret; if (length > (uintmax_t)_toRead) length = (size_t)_toRead; ret = [_socket readIntoBuffer: buffer length: length]; if (ret > length) @throw [OFOutOfRangeException exception]; _toRead -= ret; if (_toRead == 0) _atEndOfStream = true; return ret; } /* Chunked */ if (_toRead == -2) { char tmp[2]; switch ([_socket readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') @throw [OFInvalidServerReplyException exception]; case 1: _toRead++; if (tmp[0] != '\r') @throw [OFInvalidServerReplyException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead == -1) { char tmp; if ([_socket readIntoBuffer: &tmp length: 1] == 1) { _toRead++; if (tmp != '\n') @throw [OFInvalidServerReplyException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { if (length > (uintmax_t)_toRead) length = (size_t)_toRead; length = [_socket readIntoBuffer: buffer length: length]; _toRead -= length; if (_toRead == 0) _toRead = -2; return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; of_range_t range; @try { line = [_socket tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidServerReplyException exception]; } if (line == nil) return 0; range = [line rangeOfString: @";"]; if (range.location != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, range.location)]; if (line.length < 1) { /* * We have read the empty string because the socket is * at end of stream. */ if (_socket.atEndOfStream && range.location == OF_NOT_FOUND) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidServerReplyException exception]; } @try { if ((_toRead = line.hexadecimalValue) < 0) @throw [OFOutOfRangeException exception]; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } if (_toRead == 0) { _setAtEndOfStream = true; _toRead = -2; } objc_autoreleasePoolPop(pool); return 0; } } |
︙ | ︙ | |||
1116 1117 1118 1119 1120 1121 1122 | else return defaultShouldFollow(request.method, statusCode); } @end @implementation OFHTTPClient @synthesize delegate = _delegate; | | | 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 | else return defaultShouldFollow(request.method, statusCode); } @end @implementation OFHTTPClient @synthesize delegate = _delegate; @synthesize allowsInsecureRedirects = _allowsInsecureRedirects; + (instancetype)client { return [[[self alloc] init] autorelease]; } - (void)dealloc |
︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFURL *URL = request.URL; OFString *scheme = URL.scheme; | > | | 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 | - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFURL *URL = request.URL; OFString *scheme = URL.scheme; if ([scheme caseInsensitiveCompare: @"http"] != OF_ORDERED_SAME && [scheme caseInsensitiveCompare: @"https"] != OF_ORDERED_SAME) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; if (_inProgress) /* TODO: Find a better exception */ @throw [OFAlreadyConnectedException exception]; _inProgress = true; |
︙ | ︙ |
Modified src/OFHTTPCookieManager.m from [b42d33b466] to [0f44cd343b].
︙ | ︙ | |||
61 62 63 64 65 66 67 | void *pool = objc_autoreleasePoolPush(); OFString *cookieDomain, *URLHost; size_t i; if (![cookie.path hasPrefix: @"/"]) cookie.path = @"/"; | | > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | void *pool = objc_autoreleasePoolPush(); OFString *cookieDomain, *URLHost; size_t i; if (![cookie.path hasPrefix: @"/"]) cookie.path = @"/"; if (cookie.secure && [URL.scheme caseInsensitiveCompare: @"https"] != OF_ORDERED_SAME) { objc_autoreleasePoolPop(pool); return; } cookieDomain = cookie.domain.lowercaseString; cookie.domain = cookieDomain; |
︙ | ︙ | |||
121 122 123 124 125 126 127 | OFString *cookieDomain, *URLHost, *cookiePath, *URLPath; bool match; expires = cookie.expires; if (expires != nil && expires.timeIntervalSinceNow <= 0) continue; | | > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | OFString *cookieDomain, *URLHost, *cookiePath, *URLPath; bool match; expires = cookie.expires; if (expires != nil && expires.timeIntervalSinceNow <= 0) continue; if (cookie.secure && [URL.scheme caseInsensitiveCompare: @"https"] != OF_ORDERED_SAME) continue; pool = objc_autoreleasePoolPush(); cookieDomain = cookie.domain.lowercaseString; URLHost = URL.host.lowercaseString; if ([cookieDomain hasPrefix: @"."]) { |
︙ | ︙ |
Modified src/OFHTTPRequest.h from [4385937a7a] to [e39f7af9d0].
︙ | ︙ | |||
53 54 55 56 57 58 59 | /*! * @struct of_http_request_protocol_version_t \ * OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief The HTTP version of the HTTP request. */ | | > > | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /*! * @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 */ uint8_t major; /*! 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 <OFCopying> |
︙ | ︙ | |||
152 153 154 155 156 157 158 | /*! * @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 */ extern of_http_request_method_t of_http_request_method_from_string( | | | 154 155 156 157 158 159 160 161 162 163 164 165 166 | /*! * @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 */ extern of_http_request_method_t of_http_request_method_from_string( OFString *string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFHTTPRequest.m from [db732e6dff] to [2d1b69a80f].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #import "OFHTTPRequest.h" #import "OFString.h" #import "OFURL.h" #import "OFDictionary.h" #import "OFData.h" #import "OFArray.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedVersionException.h" const char * of_http_request_method_to_string(of_http_request_method_t method) { | > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #import "OFHTTPRequest.h" #import "OFString.h" #import "OFURL.h" #import "OFDictionary.h" #import "OFData.h" #import "OFArray.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedVersionException.h" const char * of_http_request_method_to_string(of_http_request_method_t method) { |
︙ | ︙ | |||
52 53 54 55 56 57 58 | return "CONNECT"; } return NULL; } of_http_request_method_t | | | | | | | | | | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | return "CONNECT"; } return NULL; } of_http_request_method_t of_http_request_method_from_string(OFString *string) { if ([string isEqual: @"OPTIONS"]) return OF_HTTP_REQUEST_METHOD_OPTIONS; if ([string isEqual: @"GET"]) return OF_HTTP_REQUEST_METHOD_GET; if ([string isEqual: @"HEAD"]) return OF_HTTP_REQUEST_METHOD_HEAD; if ([string isEqual: @"POST"]) return OF_HTTP_REQUEST_METHOD_POST; if ([string isEqual: @"PUT"]) return OF_HTTP_REQUEST_METHOD_PUT; if ([string isEqual: @"DELETE"]) return OF_HTTP_REQUEST_METHOD_DELETE; if ([string isEqual: @"TRACE"]) return OF_HTTP_REQUEST_METHOD_TRACE; if ([string isEqual: @"CONNECT"]) return OF_HTTP_REQUEST_METHOD_CONNECT; @throw [OFInvalidArgumentException exception]; } @implementation OFHTTPRequest @synthesize URL = _URL, method = _method, headers = _headers; + (instancetype)request { |
︙ | ︙ |
Modified src/OFHTTPResponse.h from [f70ef56750] to [453ae309af].
︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 | * @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 */ - (OFString *)stringWithEncoding: (of_string_encoding_t)encoding; @end OF_ASSUME_NONNULL_END | > > > > > > > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | * @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 */ - (OFString *)stringWithEncoding: (of_string_encoding_t)encoding; @end #ifdef __cplusplus extern "C" { #endif extern OFString *_Nonnull of_http_status_code_to_string(short code); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFHTTPResponse.m from [2d50b8bc91] to [1abecd6ce8].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFHTTPResponse.h" #import "OFString.h" #import "OFDictionary.h" #import "OFArray.h" #import "OFData.h" | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #import "OFHTTPResponse.h" #import "OFString.h" #import "OFDictionary.h" #import "OFArray.h" #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" OFString * of_http_status_code_to_string(short code) { switch (code) { case 100: return @"Continue"; case 101: return @"Switching Protocols"; case 200: return @"OK"; case 201: return @"Created"; case 202: return @"Accepted"; case 203: return @"Non-Authoritative Information"; case 204: return @"No Content"; case 205: return @"Reset Content"; case 206: return @"Partial Content"; case 300: return @"Multiple Choices"; case 301: return @"Moved Permanently"; case 302: return @"Found"; case 303: return @"See Other"; case 304: return @"Not Modified"; case 305: return @"Use Proxy"; case 307: return @"Temporary Redirect"; case 400: return @"Bad Request"; case 401: return @"Unauthorized"; case 402: return @"Payment Required"; case 403: return @"Forbidden"; case 404: return @"Not Found"; case 405: return @"Method Not Allowed"; case 406: return @"Not Acceptable"; case 407: return @"Proxy Authentication Required"; case 408: return @"Request Timeout"; case 409: return @"Conflict"; case 410: return @"Gone"; case 411: return @"Length Required"; case 412: return @"Precondition Failed"; case 413: return @"Request Entity Too Large"; case 414: return @"Request-URI Too Long"; case 415: return @"Unsupported Media Type"; case 416: return @"Requested Range Not Satisfiable"; case 417: return @"Expectation Failed"; case 500: return @"Internal Server Error"; case 501: return @"Not Implemented"; case 502: return @"Bad Gateway"; case 503: return @"Service Unavailable"; case 504: return @"Gateway Timeout"; case 505: return @"HTTP Version Not Supported"; default: return @"(unknown)"; } } static of_string_encoding_t encodingForContentType(OFString *contentType) { const char *UTF8String = contentType.UTF8String; size_t last, length = contentType.UTF8StringLength; enum { |
︙ | ︙ | |||
125 126 127 128 129 130 131 | if ([name isEqual: @"charset"]) charset = value; } @try { ret = of_string_parse_encoding(charset); | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | if ([name isEqual: @"charset"]) charset = value; } @try { ret = of_string_parse_encoding(charset); } @catch (OFInvalidArgumentException *e) { ret = OF_STRING_ENCODING_AUTODETECT; } return ret; } @implementation OFHTTPResponse |
︙ | ︙ |
Modified src/OFHTTPServer.m from [e03c4b06ca] to [9e1f23cc19].
︙ | ︙ | |||
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #import "OFTLSSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedProtocolException.h" #import "OFWriteFailedException.h" #import "socket_helpers.h" #define BUFFER_SIZE 1024 /* * FIXME: Key normalization replaces headers like "DNT" with "Dnt". * FIXME: Errors are not reported to the user. */ @interface OFHTTPServer () <OFTCPSocketDelegate> @end @interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving> { | > > | | | | | > | | | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #import "OFTLSSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFWriteFailedException.h" #import "socket_helpers.h" #define BUFFER_SIZE 1024 /* * FIXME: Key normalization replaces headers like "DNT" with "Dnt". * FIXME: Errors are not reported to the user. */ @interface OFHTTPServer () <OFTCPSocketDelegate> @end @interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving> { OFStreamSocket *_socket; OFHTTPServer *_server; OFHTTPRequest *_request; bool _chunked, _headersSent; } - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request; @end @interface OFHTTPServerConnection: OFObject <OFTCPSocketDelegate> { @public OFStreamSocket *_socket; OFHTTPServer *_server; OFTimer *_timer; enum { AWAITING_PROLOG, PARSING_HEADERS, SEND_RESPONSE } _state; uint8_t _HTTPMinorVersion; of_http_request_method_t _method; OFString *_host, *_path; uint16_t _port; OFMutableDictionary *_headers; size_t _contentLength; OFStream *_requestBody; } - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server; - (bool)parseProlog: (OFString *)line; - (bool)parseHeaders: (OFString *)line; - (bool)sendErrorAndClose: (short)statusCode; - (void)createResponse; @end @interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving> { OFStreamSocket *_socket; bool _chunked; intmax_t _toRead; bool _atEndOfStream, _setAtEndOfStream; } - (instancetype)initWithSocket: (OFStreamSocket *)sock chunked: (bool)chunked contentLength: (uintmax_t)contentLength; @end #ifdef OF_HAVE_THREADS @interface OFHTTPServerThread: OFThread - (void)stop; @end #endif static OF_INLINE OFString * normalizedKey(OFString *key) { char *cString = of_strdup(key.UTF8String); unsigned char *tmp = (unsigned char *)cString; bool firstLetter = true; |
︙ | ︙ | |||
229 230 231 232 233 234 235 | } return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @implementation OFHTTPServerResponse | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | } return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @implementation OFHTTPServerResponse - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request { self = [super init]; _statusCode = 500; _socket = [sock retain]; |
︙ | ︙ | |||
261 262 263 264 265 266 267 | - (void)of_sendHeaders { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | - (void)of_sendHeaders { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; [_socket writeFormat: @"HTTP/%@ %d %@\r\n", self.protocolVersionString, _statusCode, of_http_status_code_to_string(_statusCode)]; headers = [[_headers mutableCopy] autorelease]; if ([headers objectForKey: @"Date"] == nil) { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; |
︙ | ︙ | |||
316 317 318 319 320 321 322 | [self of_sendHeaders]; if (!_chunked) return [_socket writeBuffer: buffer length: length]; pool = objc_autoreleasePoolPush(); | | | < | < | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | [self of_sendHeaders]; if (!_chunked) return [_socket writeBuffer: buffer length: length]; pool = objc_autoreleasePoolPush(); [_socket writeString: [OFString stringWithFormat: @"%zX\r\n", length]]; objc_autoreleasePoolPop(pool); [_socket writeBuffer: buffer length: length]; [_socket writeString: @"\r\n"]; return length; } - (void)close { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; @try { if (!_headersSent) [self of_sendHeaders]; if (_chunked) [_socket writeString: @"0\r\n\r\n"]; } @catch (OFWriteFailedException *e) { id <OFHTTPServerDelegate> delegate = _server.delegate; if ([delegate respondsToSelector: @selector(server: didReceiveExceptionForResponse:request:exception:)]) [delegate server: _server didReceiveExceptionForResponse: self |
︙ | ︙ | |||
366 367 368 369 370 371 372 | return -1; return _socket.fileDescriptorForWriting; } @end @implementation OFHTTPServerConnection | | | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | return -1; return _socket.fileDescriptorForWriting; } @end @implementation OFHTTPServerConnection - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server { self = [super init]; @try { _socket = [sock retain]; _server = [server retain]; |
︙ | ︙ | |||
457 458 459 460 461 462 463 | pos = [line rangeOfString: @" "].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; method = [line substringWithRange: of_range(0, pos)]; @try { | | | | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | pos = [line rangeOfString: @" "].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; method = [line substringWithRange: of_range(0, pos)]; @try { _method = of_http_request_method_from_string(method); } @catch (OFInvalidArgumentException *e) { return [self sendErrorAndClose: 405]; } @try { of_range_t range = of_range(pos + 1, line.length - pos - 10); path = [[[line substringWithRange: |
︙ | ︙ | |||
490 491 492 493 494 495 496 | - (bool)parseHeaders: (OFString *)line { OFString *key, *value, *old; size_t pos; if (line.length == 0) { | > > | > > | < | > < | > > > | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | - (bool)parseHeaders: (OFString *)line { OFString *key, *value, *old; size_t pos; if (line.length == 0) { bool chunked = [[_headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; OFString *contentLengthString = [_headers objectForKey: @"Content-Length"]; intmax_t contentLength = 0; if (contentLengthString != nil) { if (chunked || contentLengthString.length == 0) return [self sendErrorAndClose: 400]; @try { contentLength = contentLengthString.decimalValue; } @catch (OFInvalidFormatException *e) { return [self sendErrorAndClose: 400]; } if (contentLength < 0) return [self sendErrorAndClose: 400]; } if (chunked || contentLengthString != nil) { [_requestBody release]; _requestBody = nil; _requestBody = [[OFHTTPServerRequestBodyStream alloc] initWithSocket: _socket chunked: chunked contentLength: contentLength]; [_timer invalidate]; [_timer release]; _timer = nil; } |
︙ | ︙ | |||
580 581 582 583 584 585 586 | } - (bool)sendErrorAndClose: (short)statusCode { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; | | | > | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | } - (bool)sendErrorAndClose: (short)statusCode { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; [_socket writeFormat: @"HTTP/1.1 %d %@\r\n" @"Date: %@\r\n" @"Server: %@\r\n" @"\r\n", statusCode, of_http_status_code_to_string(statusCode), date, _server.name]; return false; } - (void)createResponse { |
︙ | ︙ | |||
655 656 657 658 659 660 661 | response: response]; objc_autoreleasePoolPop(pool); } @end @implementation OFHTTPServerRequestBodyStream | | > > > > > | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 | response: response]; objc_autoreleasePoolPop(pool); } @end @implementation OFHTTPServerRequestBodyStream - (instancetype)initWithSocket: (OFStreamSocket *)sock chunked: (bool)chunked contentLength: (uintmax_t)contentLength { self = [super init]; @try { _socket = [sock retain]; _chunked = chunked; _toRead = contentLength; if (_chunked && _toRead > 0) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
687 688 689 690 691 692 693 | { return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { | | > < | | > > > > > > | | | | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | { return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (_socket.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ if (!_chunked) { size_t ret; if (length > (uintmax_t)_toRead) length = (size_t)_toRead; ret = [_socket readIntoBuffer: buffer length: length]; _toRead -= ret; if (_toRead == 0) _atEndOfStream = true; return ret; } /* Chunked */ if (_toRead == -2) { char tmp[2]; switch ([_socket readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') @throw [OFInvalidFormatException exception]; case 1: _toRead++; if (tmp[0] != '\r') @throw [OFInvalidFormatException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead == -1) { char tmp; if ([_socket readIntoBuffer: &tmp length: 1] == 1) { _toRead++; if (tmp != '\n') @throw [OFInvalidFormatException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { if (length > (uintmax_t)_toRead) length = (size_t)_toRead; length = [_socket readIntoBuffer: buffer length: length]; _toRead -= length; if (_toRead == 0) _toRead = -2; return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; of_range_t range; @try { line = [_socket tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidFormatException exception]; } if (line == nil) return 0; range = [line rangeOfString: @";"]; if (range.location != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, range.location)]; if (line.length < 1) { /* * We have read the empty string because the socket is * at end of stream. */ if (_socket.atEndOfStream && range.location == OF_NOT_FOUND) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidFormatException exception]; } if ((_toRead = line.hexadecimalValue) < 0) @throw [OFOutOfRangeException exception]; if (_toRead == 0) { _setAtEndOfStream = true; _toRead = -2; } objc_autoreleasePoolPop(pool); return 0; } } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _socket.hasDataInReadBuffer); } |
︙ | ︙ | |||
946 947 948 949 950 951 952 | [thread stop]; [_threadPool release]; _threadPool = nil; #endif } | | | | | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 | [thread stop]; [_threadPool release]; _threadPool = nil; #endif } - (void)of_handleAcceptedSocket: (OFStreamSocket *)acceptedSocket { OFHTTPServerConnection *connection = [[[OFHTTPServerConnection alloc] initWithSocket: acceptedSocket server: self] autorelease]; acceptedSocket.delegate = connection; [acceptedSocket asyncReadLine]; } - (bool)socket: (OFStreamSocket *)sock didAcceptSocket: (OFStreamSocket *)acceptedSocket exception: (id)exception { if (exception != nil) { if (![_delegate respondsToSelector: @selector(server:didReceiveExceptionOnListeningSocket:)]) return false; |
︙ | ︙ |
Added src/OFIPSocketAsyncConnector.h version [36d029e68c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFDNSResolver.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" OF_ASSUME_NONNULL_BEGIN @protocol OFIPSocketAsyncConnecting - (bool)of_createSocketForAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (void)of_closeSocket; @end @interface OFIPSocketAsyncConnector: OFObject <OFRunLoopConnectDelegate, OFDNSResolverHostDelegate> { id _socket; OFString *_host; uint16_t _port; id _Nullable _delegate; id _Nullable _block; id _Nullable _exception; OFData *_Nullable _socketAddresses; size_t _socketAddressesIndex; } - (instancetype)initWithSocket: (id)sock host: (OFString *)host port: (uint16_t)port delegate: (nullable id)delegate block: (nullable id)block; - (void)didConnect; - (void)tryNextAddressWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; @end OF_ASSUME_NONNULL_END |
Added src/OFIPSocketAsyncConnector.m version [6a448fb9d2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #import "OFIPSocketAsyncConnector.h" #import "OFData.h" #ifdef OF_HAVE_SCTP # import "OFSCTPSocket.h" #endif #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFConnectionFailedException.h" #import "OFInvalidFormatException.h" @implementation OFIPSocketAsyncConnector - (instancetype)initWithSocket: (id)sock host: (OFString *)host port: (uint16_t)port delegate: (id)delegate block: (id)block { self = [super init]; @try { _socket = [sock retain]; _host = [host copy]; _port = port; _delegate = [delegate retain]; _block = [block copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_socket release]; [_host release]; [_delegate release]; [_block release]; [_exception release]; [_socketAddresses release]; [super dealloc]; } - (void)didConnect { if (_exception == nil) [_socket setCanBlock: true]; #ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([_socket isKindOfClass: [OFTCPSocket class]]) ((of_tcp_socket_async_connect_block_t)_block)( _exception); # ifdef OF_HAVE_SCTP else if ([_socket isKindOfClass: [OFSCTPSocket class]]) ((of_sctp_socket_async_connect_block_t)_block)( _exception); # endif else OF_ENSURE(0); } else { #endif if ([_delegate respondsToSelector: @selector(socket:didConnectToHost:port:exception:)]) [_delegate socket: _socket didConnectToHost: _host port: _port exception: _exception]; #ifdef OF_HAVE_BLOCKS } #endif } - (void)of_socketDidConnect: (id)sock exception: (id)exception { if (exception != nil) { /* * self might be retained only by the pending async requests, * which we're about to cancel. */ [[self retain] autorelease]; [sock cancelAsyncRequests]; [sock of_closeSocket]; if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [exception retain]; [self didConnect]; } else { /* * We must not call it before returning, as otherwise * the new socket would be removed from the queue upon * return. */ OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; SEL selector = @selector(tryNextAddressWithRunLoopMode:); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: runLoop.currentMode repeats: false]; [runLoop addTimer: timer forMode: runLoop.currentMode]; } return; } [self didConnect]; } - (id)of_connectionFailedExceptionForErrNo: (int)errNo { return [OFConnectionFailedException exceptionWithHost: _host port: _port socket: _socket errNo: errNo]; } - (void)tryNextAddressWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { of_socket_address_t address = *(const of_socket_address_t *) [_socketAddresses itemAtIndex: _socketAddressesIndex++]; int errNo; of_socket_address_set_port(&address, _port); if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return; } [self tryNextAddressWithRunLoopMode: runLoopMode]; return; } #if defined(OF_NINTENDO_3DS) || defined(OF_WII) /* * On Wii and 3DS, connect() fails if non-blocking is enabled. * * Additionally, on Wii, there is no getsockopt(), so it would not be * possible to get the error (or success) after connecting anyway. * * So for now, connecting is blocking on Wii and 3DS. * * FIXME: Use a different thread as a work around. */ [_socket setCanBlock: true]; #else [_socket setCanBlock: false]; #endif if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { #if !defined(OF_NINTENDO_3DS) && !defined(OF_WII) if (errNo == EINPROGRESS) { [OFRunLoop of_addAsyncConnectForSocket: _socket mode: runLoopMode delegate: self]; return; } else { #endif [_socket of_closeSocket]; if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return; } [self tryNextAddressWithRunLoopMode: runLoopMode]; return; #if !defined(OF_NINTENDO_3DS) && !defined(OF_WII) } #endif } #if defined(OF_NINTENDO_3DS) || defined(OF_WII) [_socket setCanBlock: false]; #endif [self didConnect]; } - (void)resolver: (OFDNSResolver *)resolver didResolveHost: (OFString *)host addresses: (OFData *)addresses exception: (id)exception { if (exception != nil) { _exception = [exception retain]; [self didConnect]; return; } _socketAddresses = [addresses copy]; [self tryNextAddressWithRunLoopMode: [OFRunLoop currentRunLoop].currentMode]; } - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { @try { of_socket_address_t address = of_socket_address_parse_ip(_host, _port); _socketAddresses = [[OFData alloc] initWithItems: &address itemSize: sizeof(address) count: 1]; [self tryNextAddressWithRunLoopMode: runLoopMode]; return; } @catch (OFInvalidFormatException *e) { } [[OFThread DNSResolver] asyncResolveAddressesForHost: _host addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY runLoopMode: runLoopMode delegate: self]; } @end |
Added src/OFIPXSocket.h version [5fdb0d34da].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFDatagramSocket.h" OF_ASSUME_NONNULL_BEGIN @class OFString; /*! * @protocol OFIPXSocketDelegate OFIPXSocket.h ObjFW/OFIPXSocket.h * * @brief A delegate for OFIPXSocket. */ @protocol OFIPXSocketDelegate <OFDatagramSocketDelegate> @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 * @ref of_socket_address_ipx to create an address or * @ref of_socket_address_get_ipx_network to get the IPX network, * @ref of_socket_address_get_ipx_node to get the IPX node and * @ref of_socket_address_get_port to get the port (sometimes also called * socket number). * * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFIPXSocket: OFDatagramSocket { #ifndef OF_WINDOWS uint8_t _packetType; #endif OF_RESERVE_IVARS(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 <OFIPXSocketDelegate> 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. * @param packetType The packet type to use on the socket * @return The address on which this socket can be reached */ - (of_socket_address_t)bindToPort: (uint16_t)port packetType: (uint8_t)packetType; @end OF_ASSUME_NONNULL_END |
Added src/OFIPXSocket.m version [06e0564b9c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFIPXSocket.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "socket.h" #import "socket_helpers.h" @implementation OFIPXSocket @dynamic delegate; - (of_socket_address_t)bindToPort: (uint16_t)port packetType: (uint8_t)packetType { const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; of_socket_address_t address; int protocol = 0; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = of_socket_address_ipx(zeroNode, 0, port); #ifdef OF_WINDOWS protocol = NSPROTO_IPX + packetType; #else _packetType = address.sockaddr.ipx.sipx_type = packetType; #endif if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, protocol)) == INVALID_SOCKET) @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: of_socket_errno()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OF_SOCKET_ADDRESS_FAMILY_IPX; address.length = (socklen_t)sizeof(address.sockaddr); if (of_getsockname(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family != AF_IPX) { closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: EAFNOSUPPORT]; } return address; } #ifndef OF_WINDOWS - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_socket_address_t *)receiver { of_socket_address_t fixedReceiver; memcpy(&fixedReceiver, receiver, sizeof(fixedReceiver)); /* If it's not IPX, no fix-up needed - it will fail anyway. */ if (fixedReceiver.family == OF_SOCKET_ADDRESS_FAMILY_IPX) fixedReceiver.sockaddr.ipx.sipx_type = _packetType; [super sendBuffer: buffer length: length receiver: &fixedReceiver]; } #endif @end |
Modified src/OFInvertedCharacterSet.h from [3c2c08c41b] to [08af99fb50].
︙ | ︙ | |||
21 22 23 24 25 26 27 | @interface OFInvertedCharacterSet: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } | | < | 21 22 23 24 25 26 27 28 29 30 31 | @interface OFInvertedCharacterSet: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet; @end OF_ASSUME_NONNULL_END |
Modified src/OFInvertedCharacterSet.m from [8e068ed400] to [33cd491c87].
︙ | ︙ | |||
24 25 26 27 28 29 30 | @implementation OFInvertedCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } | | > | | | > > > > > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | @implementation OFInvertedCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @try { _characterSet = [characterSet retain]; _characterIsMember = (bool (*)(id, SEL, of_unichar_t)) [_characterSet methodForSelector: @selector(characterIsMember:)]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_characterSet release]; |
︙ | ︙ |
Modified src/OFLocale.h from [6fa1140bc7] to [dfcb090c6e].
︙ | ︙ | |||
179 180 181 182 183 184 185 | * the localized string. * * @note Generally, you want to use @ref OF_LOCALIZED instead, which also takes * care of the `nil` sentinel automatically. * * @param ID The ID for the localized string * @param fallback The fallback to use in case the localized string cannot be | | > < | | > | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | * the localized string. * * @note Generally, you want to use @ref OF_LOCALIZED instead, which also takes * care of the `nil` sentinel automatically. * * @param ID The ID for the localized string * @param fallback The fallback to use in case the localized string cannot be * looked up or is missing. This can also be an array and use * plural scripting, just like with the JSON language files. * @return The localized string */ - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (id)fallback, ... OF_SENTINEL; /*! * @brief Returns the localized string for the specified ID, using the fallback * string if it cannot be looked up or is missing. * * @note This takes a variadic argument, terminated by `nil` and passed as * va_list, that consists of pairs of variable names and variable values, * which will be replaced inside the localized string. For example, you * can pass `@"name", @"foo", nil`, causing `%[name]` to be replaced with * `foo` in the localized string. * * @note Generally, you want to use @ref OF_LOCALIZED instead, which also takes * care of the `nil` sentinel automatically. * * @param ID The ID for the localized string * @param fallback The fallback to use in case the localized string cannot be * looked up or is missing. This can also be an array and use * plural scripting, just like with the JSON language files. * @param arguments A va_list of arguments, consisting of pairs of variable * names and values to replace in the localized string, * terminated with `nil` * @return The localized string */ - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (id)fallback arguments: (va_list)arguments; @end OF_ASSUME_NONNULL_END |
Modified src/OFLocale.m from [36d525a782] to [2f0ab9defe].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 | #include <locale.h> #import "OFLocale.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" | > | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <locale.h> #import "OFLocale.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFNumber.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" #ifdef OF_AMIGAOS # include <proto/dos.h> # include <proto/exec.h> # include <proto/locale.h> #endif static OFLocale *currentLocale = nil; static OFDictionary *operatorPrecedences = nil; #ifndef OF_AMIGAOS static void parseLocale(char *locale, of_string_encoding_t *encoding, OFString **language, OFString **territory) { if ((locale = of_strdup(locale)) == NULL) |
︙ | ︙ | |||
58 59 60 61 62 63 64 | *tmp++ = '\0'; @try { if (encoding != NULL) *encoding = of_string_parse_encoding( [OFString stringWithCString: tmp encoding: enc]); | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | *tmp++ = '\0'; @try { if (encoding != NULL) *encoding = of_string_parse_encoding( [OFString stringWithCString: tmp encoding: enc]); } @catch (OFInvalidArgumentException *e) { } } /* Territory */ if ((tmp = strrchr(locale, '_')) != NULL) { *tmp++ = '\0'; if (territory != NULL) *territory = [OFString stringWithCString: tmp encoding: enc]; } if (language != NULL) *language = [OFString stringWithCString: locale encoding: enc]; } @finally { free(locale); } } #endif static bool evaluateCondition(OFString *condition, OFDictionary *variables) { OFMutableArray *tokens, *operators, *stack; /* Empty condition is the fallback that's always true */ if (condition.length == 0) return true; /* * Dirty hack to allow not needing spaces after "!" or "(" and spaces * before ")". * TODO: Replace with a proper tokenizer. */ condition = [condition stringByReplacingOccurrencesOfString: @"!" withString: @"! "]; condition = [condition stringByReplacingOccurrencesOfString: @"(" withString: @"( "]; condition = [condition stringByReplacingOccurrencesOfString: @")" withString: @" )"]; /* Substitute variables and convert to RPN first */ tokens = [OFMutableArray array]; operators = [OFMutableArray array]; for (OFString *token in [condition componentsSeparatedByString: @" " options: OF_STRING_SKIP_EMPTY]) { unsigned precedence; of_unichar_t c; if ([token isEqual: @"("]) { [operators addObject: @"("]; continue; } if ([token isEqual: @")"]) { for (;;) { OFString *operator = operators.lastObject; if (operator == nil) @throw [OFInvalidFormatException exception]; if ([operator isEqual: @"("]) { [operators removeLastObject]; break; } [tokens addObject: operator]; [operators removeLastObject]; } continue; } precedence = [[operatorPrecedences objectForKey: token] unsignedIntValue]; if (precedence > 0) { for (;;) { OFNumber *operator = operators.lastObject; unsigned otherPrecedence; if (operator == nil || [operator isEqual: @"("]) break; otherPrecedence = [[operatorPrecedences objectForKey: operator] unsignedIntValue]; if (otherPrecedence >= precedence) break; [tokens addObject: operator]; [operators removeLastObject]; } [operators addObject: token]; continue; } c = [token characterAtIndex: 0]; if ((c < '0' || c > '9') && c != '-') if ((token = [variables objectForKey: token]) == nil) @throw [OFInvalidFormatException exception]; [tokens addObject: [OFNumber numberWithDouble: token.doubleValue]]; } for (size_t i = operators.count; i > 0; i--) { OFString *operator = [operators objectAtIndex: i - 1]; if ([operator isEqual: @"("]) @throw [OFInvalidFormatException exception]; [tokens addObject: operator]; } /* Evaluate RPN */ stack = [OFMutableArray array]; for (id token in tokens) { unsigned precedence = [[operatorPrecedences objectForKey: token] unsignedIntValue]; id var, first, second; size_t stackSize; /* Only unary operators have precedence 1 */ if (precedence > 1) { stackSize = stack.count; first = [stack objectAtIndex: stackSize - 2]; second = [stack objectAtIndex: stackSize - 1]; if ([token isEqual: @"=="]) var = [OFNumber numberWithBool: [first isEqual: second]]; else if ([token isEqual: @"!="]) var = [OFNumber numberWithBool: ![first isEqual: second]]; else if ([token isEqual: @"<"]) var = [OFNumber numberWithBool: [first compare: second] == OF_ORDERED_ASCENDING]; else if ([token isEqual: @"<="]) var = [OFNumber numberWithBool: [first compare: second] != OF_ORDERED_DESCENDING]; else if ([token isEqual: @">"]) var = [OFNumber numberWithBool: [first compare: second] == OF_ORDERED_DESCENDING]; else if ([token isEqual: @">="]) var = [OFNumber numberWithBool: [first compare: second] != OF_ORDERED_ASCENDING]; else if ([token isEqual: @"+"]) var = [OFNumber numberWithDouble: [first doubleValue] + [second doubleValue]]; else if ([token isEqual: @"%"]) var = [OFNumber numberWithIntMax: [first intMaxValue] % [second intMaxValue]]; else if ([token isEqual: @"&&"]) var = [OFNumber numberWithBool: [first boolValue] && [second boolValue]]; else if ([token isEqual: @"||"]) var = [OFNumber numberWithBool: [first boolValue] || [second boolValue]]; else OF_ENSURE(0); [stack replaceObjectAtIndex: stackSize - 2 withObject: var]; [stack removeLastObject]; } else if (precedence == 1) { stackSize = stack.count; first = stack.lastObject; if ([token isEqual: @"!"]) var = [OFNumber numberWithBool: ![first boolValue]]; else if ([token isEqual: @"is_real"]) var = [OFNumber numberWithBool: [first doubleValue] != [first intMaxValue]]; else OF_ENSURE(0); [stack replaceObjectAtIndex: stackSize - 1 withObject: var]; } else [stack addObject: token]; } if (stack.count != 1) @throw [OFInvalidFormatException exception]; return [stack.firstObject boolValue]; } static OFString * evaluateConditionals(OFArray *conditions, OFDictionary *variables) { for (OFDictionary *dictionary in conditions) { OFString *condition, *value; bool found = false; for (OFString *key in dictionary) { if (found) @throw [OFInvalidFormatException exception]; condition = key; value = [dictionary objectForKey: key]; if (![condition isKindOfClass: [OFString class]] || ![value isKindOfClass: [OFString class]]) @throw [OFInvalidFormatException exception]; found = true; } if (!found) @throw [OFInvalidFormatException exception]; if (evaluateCondition(condition, variables)) return value; } /* Need to have a fallback as the last one. */ @throw [OFInvalidFormatException exception]; } static OFString * evaluateArray(OFArray *array, OFDictionary *variables) { OFMutableString *string = [OFMutableString string]; for (id object in array) { if ([object isKindOfClass: [OFString class]]) [string appendString: object]; else if ([object isKindOfClass: [OFArray class]]) [string appendString: evaluateConditionals(object, variables)]; else @throw [OFInvalidFormatException exception]; } [string makeImmutable]; return string; } @implementation OFLocale @synthesize language = _language, territory = _territory, encoding = _encoding; @synthesize decimalPoint = _decimalPoint; + (void)initialize { OFNumber *one, *two, *three, *four; if (self != [OFLocale class]) return; /* 1 is also used to denote a unary operator. */ one = [OFNumber numberWithUnsignedInt: 1]; two = [OFNumber numberWithUnsignedInt: 2]; three = [OFNumber numberWithUnsignedInt: 3]; four = [OFNumber numberWithUnsignedInt: 4]; operatorPrecedences = [[OFDictionary alloc] initWithKeysAndObjects: @"==", two, @"!=", two, @"<", two, @"<=", two, @">", two, @">=", two, @"+", two, @"%", two, @"&&", three, @"||", four, @"!", one, @"is_real", one, nil]; } + (OFLocale *)currentLocale { return currentLocale; } + (OFString *)language |
︙ | ︙ | |||
178 179 180 181 182 183 184 | # endif of_string_encoding_t ASCII = OF_STRING_ENCODING_ASCII; @try { _encoding = of_string_parse_encoding( [OFString stringWithCString: buffer encoding: ASCII]); | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | # endif of_string_encoding_t ASCII = OF_STRING_ENCODING_ASCII; @try { _encoding = of_string_parse_encoding( [OFString stringWithCString: buffer encoding: ASCII]); } @catch (OFInvalidArgumentException *e) { _encoding = OF_STRING_ENCODING_ISO_8859_1; } } else _encoding = OF_STRING_ENCODING_ISO_8859_1; /* * Get it via localeconv() instead of from the Locale struct, |
︙ | ︙ | |||
201 202 203 204 205 206 207 | if (GetVar("Language", buffer, sizeof(buffer), 0) > 0) _language = [[OFString alloc] initWithCString: buffer encoding: _encoding]; if ((locale = OpenLocale(NULL)) != NULL) { @try { | < | < < | | | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | if (GetVar("Language", buffer, sizeof(buffer), 0) > 0) _language = [[OFString alloc] initWithCString: buffer encoding: _encoding]; if ((locale = OpenLocale(NULL)) != NULL) { @try { uint32_t territory; size_t length; territory = OF_BSWAP32_IF_LE(locale->loc_CountryCode); for (length = 0; length < 4; length++) if (((char *)&territory)[length] == 0) break; _territory = [[OFString alloc] initWithCString: (char *)&territory encoding: _encoding length: length]; } @finally { CloseLocale(locale); } } |
︙ | ︙ | |||
291 292 293 294 295 296 297 | [[OFString stringWithContentsOfFile: languageFile] JSONValue]]; objc_autoreleasePoolPop(pool); } #endif - (OFString *)localizedStringForID: (OFConstantString *)ID | | | > > > > > > > | > > > | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | [[OFString stringWithContentsOfFile: languageFile] JSONValue]]; objc_autoreleasePoolPop(pool); } #endif - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (id)fallback, ... { OFString *ret; va_list args; va_start(args, fallback); ret = [self localizedStringForID: ID fallback: fallback arguments: args]; va_end(args); return ret; } - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (id)fallback arguments: (va_list)arguments { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *variables; OFConstantString *name; const char *UTF8String = NULL; size_t last, UTF8StringLength; int state = 0; variables = [OFMutableDictionary dictionary]; while ((name = va_arg(arguments, OFConstantString *)) != nil) [variables setObject: va_arg(arguments, id) forKey: name]; for (OFDictionary *strings in _localizedStrings) { id string = [strings objectForKey: ID]; if (string == nil) continue; if ([string isKindOfClass: [OFArray class]]) string = evaluateArray(string, variables); UTF8String = [string UTF8String]; UTF8StringLength = [string UTF8StringLength]; break; } if (UTF8String == NULL) { if ([fallback isKindOfClass: [OFArray class]]) fallback = evaluateArray(fallback, variables); UTF8String = [fallback UTF8String]; UTF8StringLength = [fallback UTF8StringLength]; } state = 0; last = 0; for (size_t i = 0; i < UTF8StringLength; i++) { switch (state) { case 0: |
︙ | ︙ | |||
358 359 360 361 362 363 364 | } else { [ret appendString: @"%"]; state = 0; } break; case 2: if (UTF8String[i] == ']') { | < < < | < < < < < < < < < | < < < < < | < < < < | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | } else { [ret appendString: @"%"]; state = 0; } break; case 2: if (UTF8String[i] == ']') { OFString *var = [OFString stringWithUTF8String: UTF8String + last length: i - last]; OFString *value = [variables objectForKey: var]; if (value != nil) [ret appendString: value.description]; last = i + 1; state = 0; } break; } } |
︙ | ︙ |
Modified src/OFMD5Hash.h from [afbdcd7e31] to [7314ebcbd4].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @interface OFMD5Hash: OFObject <OFCryptoHash> { OFSecureData *_iVarsData; struct of_md5_hash_ivars { uint32_t state[4]; uint64_t bits; union of_md5_hash_buffer { | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | @interface OFMD5Hash: OFObject <OFCryptoHash> { OFSecureData *_iVarsData; struct of_md5_hash_ivars { uint32_t state[4]; uint64_t bits; union of_md5_hash_buffer { unsigned char bytes[64]; uint32_t words[16]; } buffer; size_t bufferLength; } *_iVars; bool _allowsSwappableMemory; bool _calculated; } |
︙ | ︙ |
Modified src/OFMapTable.h from [39846c8467] to [18718d5a71].
︙ | ︙ | |||
23 24 25 26 27 28 29 | /*! @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. */ | | > | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /*! @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 */ void *_Nullable (*_Nullable retain)(void *_Nullable object); /*! The function to release keys / objects */ void (*_Nullable release)(void *_Nullable object); /*! The function to hash keys */ uint32_t (*_Nullable hash)(void *_Nullable object); /*! 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 |
︙ | ︙ |
Modified src/OFMutableArray.h from [9d4047891f] to [5d8e847393].
︙ | ︙ | |||
200 201 202 203 204 205 206 | */ - (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 | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | */ - (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 * Possible values are: * Value | Description * ---------------------------|------------------------- * `OF_ARRAY_SORT_DESCENDING` | Sort in descending order */ - (void)sortUsingSelector: (SEL)selector |
︙ | ︙ |
Modified src/OFMutableDictionary.h from [50c90d0e94] to [ceac8e2f46].
︙ | ︙ | |||
64 65 66 67 68 69 70 | * @return An initialized OFMutableDictionary */ - (instancetype)initWithCapacity: (size_t)capacity; /*! * @brief Sets an object for a key. * | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | * @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 * @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. * * @param key The key to set * @param object The object to set the key to. If it is nil, this is equal to * calling @ref removeObjectForKey:. */ |
︙ | ︙ |
Modified src/OFMutableString.h from [dd3e9e1fa2] to [7d782f5154].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * 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. */ | > > > | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | * * 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. */ #ifndef OBJFW_OF_MUTABLE_STRING_H #define OBJFW_OF_MUTABLE_STRING_H #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 /*! |
︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 | - (void)deleteEnclosingWhitespaces; /*! * @brief Converts the mutable string to an immutable string. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END | > > > | 212 213 214 215 216 217 218 219 220 221 222 223 | - (void)deleteEnclosingWhitespaces; /*! * @brief Converts the mutable string to an immutable string. */ - (void)makeImmutable; @end #endif OF_ASSUME_NONNULL_END #endif |
Modified src/OFNumber.m from [5a67a624f2] to [f96cb2d4be].
︙ | ︙ | |||
554 555 556 557 558 559 560 | */ _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"]) { | < < < < < < < < | < < < < < | < | | | > > | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | */ _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 @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
1071 1072 1073 1074 1075 1076 1077 | type &= ~OF_NUMBER_TYPE_FLOAT; } } OF_HASH_INIT(hash); if (type & OF_NUMBER_TYPE_FLOAT) { | < | < < | | | 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | type &= ~OF_NUMBER_TYPE_FLOAT; } } OF_HASH_INIT(hash); if (type & OF_NUMBER_TYPE_FLOAT) { 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; } |
︙ | ︙ | |||
1214 1215 1216 1217 1218 1219 1220 | 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: | | | < < < < < < < < | | > | < < < < < < < | | | > | 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 | 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: [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: @throw [OFInvalidFormatException exception]; } [element retain]; |
︙ | ︙ |
Modified src/OFObject.h from [67744f52d1] to [0775955f65].
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * * 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 "objfw-defs.h" #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <limits.h> | > > > | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | * * 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. */ #ifndef OBJFW_OF_OBJECT_H #define OBJFW_OF_OBJECT_H #include "objfw-defs.h" #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <limits.h> #include "macros.h" #include "block.h" /* * Some versions of MinGW require <winsock2.h> to be included before * <windows.h>. Do this here to make sure this is always done in the correct * order, even if another header includes just <windows.h>. */ #ifdef __MINGW32__ |
︙ | ︙ | |||
84 85 86 87 88 89 90 | } of_byte_order_t; /*! * @struct of_range_t OFObject.h ObjFW/OFObject.h * * @brief A range. */ | | > | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | } 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 */ size_t location; /*! 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 |
︙ | ︙ | |||
135 136 137 138 139 140 141 | typedef double of_time_interval_t; /*! * @struct of_point_t OFObject.h ObjFW/OFObject.h * * @brief A point. */ | | > | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 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 */ float x; /*! 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 |
︙ | ︙ | |||
181 182 183 184 185 186 187 | } /*! * @struct of_dimension_t OFObject.h ObjFW/OFObject.h * * @brief A dimension. */ | | > | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | } /*! * @struct of_dimension_t OFObject.h ObjFW/OFObject.h * * @brief A dimension. */ struct OF_BOXABLE of_dimension_t { /*! The width of the dimension */ float width; /*! 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 |
︙ | ︙ | |||
227 228 229 230 231 232 233 | } /*! * @struct of_rectangle_t OFObject.h ObjFW/OFObject.h * * @brief A rectangle. */ | | > | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | } /*! * @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 */ of_point_t origin; /*! 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 |
︙ | ︙ | |||
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | if (!of_dimension_equal(rectangle1.size, rectangle2.size)) return false; return true; } @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. */ | > | | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | if (!of_dimension_equal(rectangle1.size, rectangle2.size)) return false; return true; } #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; /*! |
︙ | ︙ | |||
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | /*! * @brief Retain a weak reference to this object. * * @return Whether a weak reference to this object has been retained */ - (bool)retainWeakReference; @end /*! * @class OFObject OFObject.h ObjFW/OFObject.h * * @brief The root class for all other classes inside ObjFW. */ OF_ROOT_CLASS @interface OFObject <OFObject> { @private | > > | | | | | | | | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | /*! * @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__ OF_ROOT_CLASS @interface OFObject <OFObject> { @private # ifndef __clang_analyzer__ Class _isa; # else Class _isa __attribute__((__unused__)); # endif } # ifdef OF_HAVE_CLASS_PROPERTIES # ifndef __cplusplus @property (class, readonly, nonatomic) Class class; # else @property (class, readonly, nonatomic, getter=class) Class class_; # endif @property (class, readonly, nonatomic) OFString *className; @property (class, readonly, nullable, nonatomic) Class superclass; @property (class, readonly, nonatomic) OFString *description; # endif /*! * @brief The name of the object's class. */ @property (readonly, nonatomic) OFString *className; /*! |
︙ | ︙ | |||
733 734 735 736 737 738 739 | * @return The class of the object */ + (id)copy; /*! * @brief Initializes an already allocated object. * | | | > > > > > > > > > > > > > > | > > > > | | | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | * @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]; * * @try { * // Custom initialization code goes here. * } @catch (id e) { * [self release]; * @throw e; * } * * return self; * @endcode * * With ARC enabled, the following pattern needs to be used instead: * @code * self = [super init]; * * // Custom initialization code goes here. * * return self; * @endcode * * @ref init may never return `nil`, instead an exception (for example * @ref OFInitializationFailedException) should be thrown. * * @return An initialized object */ - (instancetype)init; /*! * @brief Returns the method signature for the specified selector. |
︙ | ︙ | |||
933 934 935 936 937 938 939 | - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 afterDelay: (of_time_interval_t)delay; | | | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 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 */ |
︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 | - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 afterDelay: (of_time_interval_t)delay; | | | 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 | - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 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`, |
︙ | ︙ | |||
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 | * @warning If you override this method, you must make sure that it never * returns! * * @param selector The selector not understood by the receiver */ - (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN; @end /*! * @protocol OFCopying OFObject.h ObjFW/OFObject.h * * @brief A protocol for the creation of copies. */ @protocol OFCopying /*! | > > > > | 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | * @warning If you override this method, you must make sure that it never * returns! * * @param selector The selector not understood by the receiver */ - (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN; @end #else typedef void OFObject; #endif #ifdef __OBJC__ /*! * @protocol OFCopying OFObject.h ObjFW/OFObject.h * * @brief A protocol for the creation of copies. */ @protocol OFCopying /*! |
︙ | ︙ | |||
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 | * @brief Compares the object with another object. * * @param object An object to compare the object to * @return The result of the comparison */ - (of_comparison_result_t)compare: (id <OFComparing>)object; @end #ifdef __cplusplus extern "C" { #endif #ifdef OF_APPLE_RUNTIME extern void *_Null_unspecified objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void *_Null_unspecified pool); #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); extern uint32_t of_hash_seed; #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END | > > | | > > > | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 | * @brief Compares the object with another object. * * @param object An object to compare the object to * @return The result of the comparison */ - (of_comparison_result_t)compare: (id <OFComparing>)object; @end #endif #ifdef __cplusplus extern "C" { #endif #ifdef OF_APPLE_RUNTIME extern void *_Null_unspecified objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void *_Null_unspecified pool); #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); extern uint32_t of_hash_seed; #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #ifdef __OBJC__ # import "OFObject+KeyValueCoding.h" # import "OFObject+Serialization.h" #endif #endif |
Modified src/OFOptionsParser.h from [0f3268b0df] to [d206f16719].
︙ | ︙ | |||
23 24 25 26 27 28 29 | 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. */ | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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. */ of_unichar_t shortOption; /*! * The long version (e.g. `--verbose`) of the option or `nil` for none. */ OFString *__unsafe_unretained _Nullable longOption; |
︙ | ︙ | |||
51 52 53 54 55 56 57 | /*! * An optional pointer to a bool that is set to whether the option has * been specified. */ bool *_Nullable isSpecifiedPtr; /*! | | > | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /*! * 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 |
︙ | ︙ |
Modified src/OFPlugin.m from [3e825cedc9] to [539230b0ba].
︙ | ︙ | |||
21 22 23 24 25 26 27 28 | #include <string.h> #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFPlugin.h" #import "OFString.h" | > | > | > > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <string.h> #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFPlugin.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLoadPluginFailedException.h" typedef OFPlugin *(*init_plugin_t)(void); of_plugin_handle_t of_dlopen(OFString *path, int flags) { #ifndef OF_WINDOWS return dlopen([path cStringWithEncoding: [OFLocale encoding]], flags); #else if (path == nil) return GetModuleHandle(NULL); if ([OFSystemInfo isWindowsNT]) return LoadLibraryW(path.UTF16String); else return LoadLibraryA( [path cStringWithEncoding: [OFLocale encoding]]); #endif } void * of_dlsym(of_plugin_handle_t handle, const char *symbol) { #ifndef OF_WINDOWS |
︙ | ︙ |
Modified src/OFProcess.h from [b0e3da0617] to [376740648e].
︙ | ︙ | |||
193 194 195 196 197 198 199 200 201 202 | * @brief Closes the write direction of the process. * * This method needs to be called for some programs before data can be read, * since some programs don't start processing before the write direction is * closed. */ - (void)closeForWriting; @end OF_ASSUME_NONNULL_END | > > > > > > > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | * @brief Closes the write direction of the process. * * This method needs to be called for some programs before data can be read, * since some programs don't start processing before the write direction is * closed. */ - (void)closeForWriting; /*! * @brief Waits for the process to terminate and returns the exit status. * * If the process has already exited, this returns the exit status immediately. */ - (int)waitForTermination; @end OF_ASSUME_NONNULL_END |
Modified src/OFRIPEMD160Hash.h from [b0c573b36f] to [bd428762b3].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @interface OFRIPEMD160Hash: OFObject <OFCryptoHash> { OFSecureData *_iVarsData; struct of_ripemd160_hash_ivars { uint32_t state[5]; uint64_t bits; union of_ripemd160_hash_buffer { | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | @interface OFRIPEMD160Hash: OFObject <OFCryptoHash> { OFSecureData *_iVarsData; struct of_ripemd160_hash_ivars { uint32_t state[5]; uint64_t bits; union of_ripemd160_hash_buffer { unsigned char bytes[64]; uint32_t words[16]; } buffer; size_t bufferLength; } *_iVars; bool _allowsSwappableMemory; bool _calculated; } |
︙ | ︙ |
Modified src/OFRunLoop+Private.h from [f938cc8f46] to [f46c29fa91].
︙ | ︙ | |||
14 15 16 17 18 19 20 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFRunLoop.h" #import "OFStream.h" #ifdef OF_HAVE_SOCKETS | | > | | | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFRunLoop.h" #import "OFStream.h" #ifdef OF_HAVE_SOCKETS # import "OFDatagramSocket.h" # import "OFSequencedPacketSocket.h" # import "OFStreamSocket.h" #endif OF_ASSUME_NONNULL_BEGIN #ifdef OF_HAVE_SOCKETS @protocol OFRunLoopConnectDelegate <OFObject> - (void)of_socketDidConnect: (id)socket exception: (nullable id)exception; - (id)of_connectionFailedExceptionForErrNo: (int)errNo; @end #endif @interface OFRunLoop () + (void)of_setMainRunLoop: (OFRunLoop *)runLoop; #ifdef OF_HAVE_SOCKETS + (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *) |
︙ | ︙ | |||
79 80 81 82 83 84 85 | # ifdef OF_HAVE_BLOCKS block: (nullable of_stream_async_write_string_block_t) block # endif delegate: (nullable id <OFStreamDelegate>)delegate; # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) | | | < | | | < | < < < | < | | | | > > > > > > > > | > > > > > > > > | < | < | > | < | | < < | < | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | # ifdef OF_HAVE_BLOCKS block: (nullable of_stream_async_write_string_block_t) block # endif delegate: (nullable id <OFStreamDelegate>)delegate; # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + (void)of_addAsyncConnectForSocket: (id)socket mode: (of_run_loop_mode_t)mode delegate: (id <OFRunLoopConnectDelegate>)delegate; # endif + (void)of_addAsyncAcceptForSocket: (id)socket mode: (of_run_loop_mode_t)mode block: (nullable id)block delegate: (nullable id)delegate; + (void)of_addAsyncReceiveForDatagramSocket: (OFDatagramSocket *)socket buffer: (void *)buffer length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (nullable of_datagram_socket_async_receive_block_t)block # endif delegate: (nullable id <OFDatagramSocketDelegate>) delegate; + (void)of_addAsyncSendForDatagramSocket: (OFDatagramSocket *)socket data: (OFData *)data receiver: (const of_socket_address_t *)receiver mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (nullable of_datagram_socket_async_send_data_block_t)block # endif delegate: (nullable id <OFDatagramSocketDelegate>)delegate; + (void)of_addAsyncReceiveForSequencedPacketSocket: (OFSequencedPacketSocket *)socket buffer: (void *)buffer length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (nullable of_sequenced_packet_socket_async_receive_block_t)block # endif delegate: (nullable id <OFSequencedPacketSocketDelegate>) delegate; + (void)of_addAsyncSendForSequencedPacketSocket: (OFSequencedPacketSocket *)socket data: (OFData *)data mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (nullable of_sequenced_packet_socket_async_send_data_block_t)block # endif delegate: (nullable id <OFSequencedPacketSocketDelegate>)delegate; + (void)of_cancelAsyncRequestsForObject: (id)object mode: (of_run_loop_mode_t)mode; #endif - (void)of_removeTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode; @end OF_ASSUME_NONNULL_END |
Modified src/OFRunLoop.m from [ac74ecd3ae] to [8701d2b9f0].
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFArray.h" #import "OFData.h" #import "OFDictionary.h" #ifdef OF_HAVE_SOCKETS # import "OFKernelEventObserver.h" | > > > | | < < < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFArray.h" #import "OFData.h" #import "OFDictionary.h" #ifdef OF_HAVE_SOCKETS # import "OFKernelEventObserver.h" # import "OFDatagramSocket.h" # import "OFSequencedPacketSocket.h" # import "OFSequencedPacketSocket+Private.h" # import "OFStreamSocket.h" # import "OFStreamSocket+Private.h" #endif #import "OFThread.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" # import "OFCondition.h" #endif #import "OFSortedList.h" #import "OFTimer.h" #import "OFTimer+Private.h" #import "OFDate.h" #import "OFObserveFailedException.h" of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default"; static OFRunLoop *mainRunLoop = nil; @interface OFRunLoopState: OFObject #ifdef OF_HAVE_SOCKETS <OFKernelEventObserverDelegate> |
︙ | ︙ | |||
153 154 155 156 157 158 159 | @end # endif @interface OFRunLoopAcceptQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS | > > > > | > > > > > > > > > > > > > > > > > > | | | | < | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | @end # endif @interface OFRunLoopAcceptQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS id _block; # endif } @end @interface OFRunLoopDatagramReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_datagram_socket_async_receive_block_t _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopDatagramSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_datagram_socket_async_send_data_block_t _block; # endif OFData *_data; of_socket_address_t _receiver; } @end @interface OFRunLoopPacketReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_sequenced_packet_socket_async_receive_block_t _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopPacketSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_sequenced_packet_socket_async_send_data_block_t _block; # endif OFData *_data; } @end #endif @implementation OFRunLoopState - (instancetype)init { |
︙ | ︙ | |||
414 415 416 417 418 419 420 | } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) | | | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(length, exception); else { # endif if (![_delegate respondsToSelector: @selector(stream:didReadIntoBuffer:length:exception:)]) return false; return [_delegate stream: object |
︙ | ︙ | |||
462 463 464 465 466 467 468 | if (_readLength != _exactLength && ![object isAtEndOfStream] && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { | | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | if (_readLength != _exactLength && ![object isAtEndOfStream] && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { if (!_block(_readLength, exception)) return false; _readLength = 0; return true; } else { # endif if (![_delegate respondsToSelector: |
︙ | ︙ | |||
514 515 516 517 518 519 520 | } if (line == nil && ![object isAtEndOfStream] && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) | | | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | } if (line == nil && ![object isAtEndOfStream] && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(line, exception); else { # endif if (![_delegate respondsToSelector: @selector(stream:didReadLine:exception:)]) return false; return [_delegate stream: object |
︙ | ︙ | |||
564 565 566 567 568 569 570 | _writtenLength += length; if (_writtenLength != dataLength && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | _writtenLength += length; if (_writtenLength != dataLength && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(_data, _writtenLength, exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; |
︙ | ︙ | |||
636 637 638 639 640 641 642 | _writtenLength += length; if (_writtenLength != cStringLength && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { | | < | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | _writtenLength += length; if (_writtenLength != cStringLength && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newString = _block(_string, _writtenLength, exception); if (newString == nil) return false; oldString = _string; _string = [newString copy]; [oldString release]; |
︙ | ︙ | |||
693 694 695 696 697 698 699 | @implementation OFRunLoopConnectQueueItem - (bool)handleObject: (id)object { id exception = nil; int errNo; if ((errNo = [object of_socketError]) != 0) | < | < < | | 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | @implementation OFRunLoopConnectQueueItem - (bool)handleObject: (id)object { id exception = nil; int errNo; if ((errNo = [object of_socketError]) != 0) exception = [_delegate of_connectionFailedExceptionForErrNo: errNo]; if ([_delegate respondsToSelector: @selector(of_socketDidConnect:exception:)]) { /* * Make sure we only call the delegate once we removed the * socket from the kernel event observer. This is necessary as * otherwise we could try to connect to the next address and it |
︙ | ︙ | |||
731 732 733 734 735 736 737 | } @end # endif @implementation OFRunLoopAcceptQueueItem - (bool)handleObject: (id)object { | < | | > > | > > > > > > > | | 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | } @end # endif @implementation OFRunLoopAcceptQueueItem - (bool)handleObject: (id)object { id acceptedSocket, exception = nil; @try { acceptedSocket = [object accept]; } @catch (id e) { acceptedSocket = nil; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([object isKindOfClass: [OFStreamSocket class]]) return ((of_stream_socket_async_accept_block_t) _block)(acceptedSocket, exception); else if ([object isKindOfClass: [OFSequencedPacketSocket class]]) return ((of_sequenced_packet_socket_async_accept_block_t) _block)(acceptedSocket, exception); else OF_ENSURE(0); } else { # endif if (![_delegate respondsToSelector: @selector(socket:didAcceptSocket:exception:)]) return false; return [_delegate socket: object didAcceptSocket: acceptedSocket |
︙ | ︙ | |||
768 769 770 771 772 773 774 | [_block release]; [super dealloc]; } # endif @end | | | | 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopDatagramReceiveQueueItem - (bool)handleObject: (id)object { size_t length; of_socket_address_t address; id exception = nil; @try { length = [object receiveIntoBuffer: _buffer length: _length sender: &address]; } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(length, &address, exception); else { # endif if (![_delegate respondsToSelector: @selector( socket:didReceiveIntoBuffer:length:sender:exception:)]) return false; return [_delegate socket: object |
︙ | ︙ | |||
813 814 815 816 817 818 819 | [_block release]; [super dealloc]; } # endif @end | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopDatagramSendQueueItem - (bool)handleObject: (id)object { id exception = nil; OFData *newData, *oldData; @try { [object sendBuffer: _data.items length: _data.count * _data.itemSize receiver: &_receiver]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(_data, &_receiver, exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; return true; } else { # endif if (![_delegate respondsToSelector: @selector(socket:didSendData:receiver:exception:)]) return false; newData = [_delegate socket: object didSendData: _data receiver: &_receiver exception: exception]; if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; return true; # ifdef OF_HAVE_BLOCKS } # endif } - (void)dealloc { [_data release]; # ifdef OF_HAVE_BLOCKS [_block release]; # endif [super dealloc]; } @end @implementation OFRunLoopPacketReceiveQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { length = [object receiveIntoBuffer: _buffer length: _length]; } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(length, exception); else { # endif if (![_delegate respondsToSelector: @selector( socket:didReceiveIntoBuffer:length:exception:)]) return false; return [_delegate socket: object didReceiveIntoBuffer: _buffer length: length exception: exception]; # ifdef OF_HAVE_BLOCKS } # endif } # ifdef OF_HAVE_BLOCKS - (void)dealloc { [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopPacketSendQueueItem - (bool)handleObject: (id)object { id exception = nil; OFData *newData, *oldData; @try { [object sendBuffer: _data.items length: _data.count * _data.itemSize]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(_data, exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; return true; } else { # endif if (![_delegate respondsToSelector: @selector(socket:didSendData:exception:)]) return false; newData = [_delegate socket: object didSendData: _data exception: exception]; if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | queueItem->_string = [string copy]; queueItem->_encoding = encoding; QUEUE_ITEM } # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) | | | | > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > < | > > | | | | > > | > | | | | < | | | | < | | < | | < | 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 | queueItem->_string = [string copy]; queueItem->_encoding = encoding; QUEUE_ITEM } # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + (void)of_addAsyncConnectForSocket: (id)sock mode: (of_run_loop_mode_t)mode delegate: (id <OFRunLoopConnectDelegate>)delegate { NEW_WRITE(OFRunLoopConnectQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; QUEUE_ITEM } # endif + (void)of_addAsyncAcceptForSocket: (id)sock mode: (of_run_loop_mode_t)mode block: (id)block delegate: (id)delegate { NEW_READ(OFRunLoopAcceptQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif QUEUE_ITEM } + (void)of_addAsyncReceiveForDatagramSocket: (OFDatagramSocket *)sock buffer: (void *)buffer length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_datagram_socket_async_receive_block_t)block # endif delegate: (id <OFDatagramSocketDelegate>)delegate { NEW_READ(OFRunLoopDatagramReceiveQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncSendForDatagramSocket: (OFDatagramSocket *)sock data: (OFData *)data receiver: (const of_socket_address_t *)receiver mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_datagram_socket_async_send_data_block_t)block # endif delegate: (id <OFDatagramSocketDelegate>)delegate { NEW_WRITE(OFRunLoopDatagramSendQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; queueItem->_receiver = *receiver; QUEUE_ITEM } + (void)of_addAsyncReceiveForSequencedPacketSocket: (OFSequencedPacketSocket *) sock buffer: (void *)buffer length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_sequenced_packet_socket_async_receive_block_t)block # endif delegate: (id <OFSequencedPacketSocketDelegate>)delegate { NEW_READ(OFRunLoopPacketReceiveQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncSendForSequencedPacketSocket: (OFSequencedPacketSocket *)sock data: (OFData *)data mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_sequenced_packet_socket_async_send_data_block_t)block # endif delegate: (id <OFSequencedPacketSocketDelegate>)delegate { NEW_WRITE(OFRunLoopPacketSendQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; QUEUE_ITEM } # undef NEW_READ # undef NEW_WRITE # undef QUEUE_ITEM |
︙ | ︙ |
Added src/OFSCTPSocket.h version [946c9ca590].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFSequencedPacketSocket.h" #import "OFRunLoop.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @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 <OFSequencedPacketSocketDelegate> @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 * @param exception An exception that occurred while connecting, or nil on * success */ - (void)socket: (OFSCTPSocket *)socket 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. * * 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) } /*! * @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 <OFSCTPSocketDelegate> 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 */ - (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 */ - (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 * @param block The block to execute once the connection has been established */ - (void)asyncConnectToHost: (OFString *)host 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 * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Added src/OFSCTPSocket.m version [f509519c08].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFSCTPSocket.h" #import "OFDNSResolver.h" #import "OFData.h" #import "OFDate.h" #import "OFIPSocketAsyncConnector.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFString.h" #import "OFThread.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFGetOptionFailedException.h" #import "OFNotOpenException.h" #import "OFSetOptionFailedException.h" #import "socket.h" #import "socket_helpers.h" static const of_run_loop_mode_t connectRunLoopMode = @"of_sctp_socket_connect_mode"; @interface OFSCTPSocket () <OFIPSocketAsyncConnecting> @end @interface OFSCTPSocketConnectDelegate: OFObject <OFSCTPSocketDelegate> { @public bool _done; id _exception; } @end @implementation OFSCTPSocketConnectDelegate - (void)dealloc { [_exception release]; [super dealloc]; } - (void)socket: (OFSCTPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { _done = true; _exception = [exception retain]; } @end @implementation OFSCTPSocket @dynamic delegate; - (bool)of_createSocketForAddress: (const of_socket_address_t *)address errNo: (int *)errNo { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_socket = socket(address->sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_SCTP)) == INVALID_SOCKET) { *errNo = of_socket_errno(); return false; } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif return true; } - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (connect(_socket, &address->sockaddr.sockaddr, address->length) != 0) { *errNo = of_socket_errno(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = INVALID_SOCKET; } - (void)connectToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); id <OFSCTPSocketDelegate> delegate = _delegate; OFSCTPSocketConnectDelegate *connectDelegate = [[[OFSCTPSocketConnectDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; self.delegate = connectDelegate; [self asyncConnectToHost: host port: port runLoopMode: connectRunLoopMode]; while (!connectDelegate->_done) [runLoop runMode: connectRunLoopMode beforeDate: nil]; /* Cleanup */ [runLoop runMode: connectRunLoopMode beforeDate: [OFDate date]]; if (connectDelegate->_exception != nil) @throw connectDelegate->_exception; self.delegate = delegate; objc_autoreleasePoolPop(pool); } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port { [self asyncConnectToHost: host port: port runLoopMode: of_run_loop_mode_default]; } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; [[[[OFIPSocketAsyncConnector alloc] initWithSocket: self host: host port: port delegate: _delegate block: NULL ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port block: (of_sctp_socket_async_connect_block_t)block { [self asyncConnectToHost: host port: port runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sctp_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; [[[[OFIPSocketAsyncConnector alloc] initWithSocket: self host: host port: port delegate: nil block: block] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port { const int one = 1; void *pool = objc_autoreleasePoolPush(); OFData *socketAddresses; of_socket_address_t address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; socketAddresses = [[OFThread DNSResolver] resolveAddressesForHost: host addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY]; address = *(of_socket_address_t *)[socketAddresses itemAtIndex: 0]; of_socket_address_set_port(&address, port); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_SCTP)) == INVALID_SOCKET) @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: of_socket_errno()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, (socklen_t)sizeof(one)); if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } objc_autoreleasePoolPop(pool); if (port > 0) return port; memset(&address, 0, sizeof(address)); address.length = (socklen_t)sizeof(address.sockaddr); if (of_getsockname(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family == AF_INET) return OF_BSWAP16_IF_LE(address.sockaddr.in.sin_port); # ifdef OF_HAVE_IPV6 else if (address.sockaddr.sockaddr.sa_family == AF_INET6) return OF_BSWAP16_IF_LE(address.sockaddr.in6.sin6_port); # endif else { closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: EAFNOSUPPORT]; } } - (void)setCanDelaySendingPackets: (bool)canDelaySendingPackets { int v = !canDelaySendingPackets; if (setsockopt(_socket, IPPROTO_SCTP, SCTP_NODELAY, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; } - (bool)canDelaySendingPackets { int v; socklen_t len = sizeof(v); if (getsockopt(_socket, IPPROTO_SCTP, SCTP_NODELAY, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; return !v; } @end |
Modified src/OFSHA1Hash.h from [812276bc67] to [bd4ba48e95].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @interface OFSHA1Hash: OFObject <OFCryptoHash> { OFSecureData *_iVarsData; struct of_sha1_hash_ivars { uint32_t state[5]; uint64_t bits; union of_sha1_hash_buffer { | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | @interface OFSHA1Hash: OFObject <OFCryptoHash> { OFSecureData *_iVarsData; struct of_sha1_hash_ivars { uint32_t state[5]; uint64_t bits; union of_sha1_hash_buffer { unsigned char bytes[64]; uint32_t words[80]; } buffer; size_t bufferLength; } *_iVars; bool _allowsSwappableMemory; bool _calculated; } |
︙ | ︙ |
Modified src/OFSHA224Or256Hash.h from [9b410449c3] to [deb793f9c1].
︙ | ︙ | |||
31 32 33 34 35 36 37 | @private OFSecureData *_iVarsData; @protected struct of_sha224_or_256_hash_ivars { uint32_t state[8]; uint64_t bits; union of_sha224_or_256_hash_buffer { | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @private OFSecureData *_iVarsData; @protected struct of_sha224_or_256_hash_ivars { uint32_t state[8]; uint64_t bits; union of_sha224_or_256_hash_buffer { unsigned char bytes[64]; uint32_t words[64]; } buffer; size_t bufferLength; } *_iVars; @private bool _allowsSwappableMemory; bool _calculated; |
︙ | ︙ |
Modified src/OFSHA384Or512Hash.h from [b0f0d3732f] to [e5381155b9].
︙ | ︙ | |||
31 32 33 34 35 36 37 | @private OFSecureData *_iVarsData; @protected struct of_sha384_or_512_hash_ivars { uint64_t state[8]; uint64_t bits[2]; union of_sha384_or_512_hash_buffer { | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @private OFSecureData *_iVarsData; @protected struct of_sha384_or_512_hash_ivars { uint64_t state[8]; uint64_t bits[2]; union of_sha384_or_512_hash_buffer { unsigned char bytes[128]; uint64_t words[80]; } buffer; size_t bufferLength; } *_iVars; @private bool _allowsSwappableMemory; bool _calculated; |
︙ | ︙ |
Added src/OFSPXSocket.h version [b8282e6d38].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFSequencedPacketSocket.h" #import "OFRunLoop.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @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 <OFSequencedPacketSocketDelegate> @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 * @param port The port of the node to which the socket connected * @param exception An exception that occurred while connecting, or nil on * success */ - (void)socket: (OFSPXSocket *)socket didConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node 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, * use @ref OFSPXStreamSocket instead. * * 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) } /*! * @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 <OFSPXSocketDelegate> 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 * connect to */ - (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 * connect to */ - (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 * connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node 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 * connect to * @param block The block to execute once the connection has been established */ - (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 * connect to * @param runLoopMode The run loop mode in which to perform the async connect * @param block The block to execute once the connection has been established */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network 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 */ - (of_socket_address_t)bindToPort: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Added src/OFSPXSocket.m version [9940cead8b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #import "OFSPXSocket.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFConnectionFailedException.h" #import "OFNotOpenException.h" #import "socket.h" #import "socket_helpers.h" #ifndef NSPROTO_SPX # define NSPROTO_SPX 0 #endif #define SPX_PACKET_TYPE 5 @interface OFSPXSocket () - (int)of_createSocketForAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (void)of_closeSocket; @end @interface OFSPXSocketAsyncConnectDelegate: OFObject <OFRunLoopConnectDelegate> { OFSPXSocket *_socket; unsigned char _node[IPX_NODE_LEN]; uint32_t _network; uint16_t _port; #ifdef OF_HAVE_BLOCKS of_spx_socket_async_connect_block_t _block; #endif } - (instancetype)initWithSocket: (OFSPXSocket *)socket node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (of_spx_socket_async_connect_block_t)block #endif ; - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; @end @implementation OFSPXSocketAsyncConnectDelegate - (instancetype)initWithSocket: (OFSPXSocket *)sock node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (of_spx_socket_async_connect_block_t)block #endif { self = [super init]; @try { _socket = [sock retain]; memcpy(_node, node, IPX_NODE_LEN); _network = network; _port = port; #ifdef OF_HAVE_BLOCKS _block = [block copy]; #endif } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_socket release]; #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { of_socket_address_t address = of_socket_address_ipx(_node, _network, _port); id exception = nil; int errNo; if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { exception = [self of_connectionFailedExceptionForErrNo: errNo]; goto inform_delegate; } _socket.canBlock = false; if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { if (errNo == EINPROGRESS) { [OFRunLoop of_addAsyncConnectForSocket: _socket mode: runLoopMode delegate: self]; return; } [_socket of_closeSocket]; exception = [self of_connectionFailedExceptionForErrNo: errNo]; } inform_delegate: [self performSelector: @selector(of_socketDidConnect:exception:) withObject: _socket withObject: exception afterDelay: 0]; } - (void)of_socketDidConnect: (id)sock exception: (id)exception { id <OFSPXSocketDelegate> delegate = ((OFSPXSocket *)sock).delegate; if (exception == nil) ((OFSPXSocket *)sock).canBlock = true; #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(exception); else { #endif if ([delegate respondsToSelector: @selector(socket:didConnectToNode:network:port:exception:)]) [delegate socket: _socket didConnectToNode: _node network: _network port: _port exception: exception]; #ifdef OF_HAVE_BLOCKS } #endif } - (id)of_connectionFailedExceptionForErrNo: (int)errNo { return [OFConnectionFailedException exceptionWithNode: _node network: _network port: _port socket: _socket errNo: errNo]; } @end @implementation OFSPXSocket @dynamic delegate; - (int)of_createSocketForAddress: (const of_socket_address_t *)address errNo: (int *)errNo { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_socket = socket(address->sockaddr.ipx.sipx_family, SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET) { *errNo = of_socket_errno(); return false; } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif return true; } - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (connect(_socket, &address->sockaddr.sockaddr, address->length) != 0) { *errNo = of_socket_errno(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = INVALID_SOCKET; } - (void)connectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { of_socket_address_t address = of_socket_address_ipx(node, network, port); int errNo; if (![self of_createSocketForAddress: &address errNo: &errNo]) @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; if (![self of_connectSocketToAddress: &address errNo: &errNo]) { [self of_closeSocket]; @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; } } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { [self asyncConnectToNode: node network: network port: port runLoopMode: of_run_loop_mode_default]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port #ifdef OF_HAVE_BLOCKS block: NULL #endif ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (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 { [self asyncConnectToNode: node network: network port: port runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_spx_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port block: block ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (of_socket_address_t)bindToPort: (uint16_t)port { const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; of_socket_address_t address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = of_socket_address_ipx(zeroNode, 0, port); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET) @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: of_socket_errno()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OF_SOCKET_ADDRESS_FAMILY_IPX; address.length = (socklen_t)sizeof(address.sockaddr); if (of_getsockname(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family != AF_IPX) { closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: EAFNOSUPPORT]; } return address; } @end |
Added src/OFSPXStreamSocket.h version [722b6414cf].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFStreamSocket.h" #import "OFRunLoop.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @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 <OFStreamSocketDelegate> @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 * @param port The port of the node to which the socket connected * @param exception An exception that occurred while connecting, or nil on * success */ - (void)socket: (OFSPXStreamSocket *)socket didConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node 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, * use @ref OFSPXSocket instead. * * 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) } /*! * @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 <OFSPXStreamSocketDelegate> 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 * connect to */ - (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 * @param port The port (sometimes also called socket number) on the node to * connect to */ - (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 * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node 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 * @param port The port (sometimes also called socket number) on the node to * connect to * @param block The block to execute once the connection has been established */ - (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 * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect * @param block The block to execute once the connection has been established */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network 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 */ - (of_socket_address_t)bindToPort: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Added src/OFSPXStreamSocket.m version [cb1a9316c7].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #import "OFSPXStreamSocket.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFConnectionFailedException.h" #import "OFNotOpenException.h" #import "socket.h" #import "socket_helpers.h" #ifndef NSPROTO_SPX # define NSPROTO_SPX 0 #endif #define SPX_PACKET_TYPE 5 @interface OFSPXStreamSocket () - (int)of_createSocketForAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (void)of_closeSocket; @end @interface OFSPXStreamSocketAsyncConnectDelegate: OFObject <OFRunLoopConnectDelegate> { OFSPXStreamSocket *_socket; unsigned char _node[IPX_NODE_LEN]; uint32_t _network; uint16_t _port; #ifdef OF_HAVE_BLOCKS of_spx_stream_socket_async_connect_block_t _block; #endif } - (instancetype)initWithSocket: (OFSPXStreamSocket *)socket node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (of_spx_stream_socket_async_connect_block_t) block #endif ; - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; @end @implementation OFSPXStreamSocketAsyncConnectDelegate - (instancetype)initWithSocket: (OFSPXStreamSocket *)sock node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (of_spx_stream_socket_async_connect_block_t) block #endif { self = [super init]; @try { _socket = [sock retain]; memcpy(_node, node, IPX_NODE_LEN); _network = network; _port = port; #ifdef OF_HAVE_BLOCKS _block = [block copy]; #endif } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_socket release]; #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { of_socket_address_t address = of_socket_address_ipx(_node, _network, _port); id exception = nil; int errNo; if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { exception = [self of_connectionFailedExceptionForErrNo: errNo]; goto inform_delegate; } _socket.canBlock = false; if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { if (errNo == EINPROGRESS) { [OFRunLoop of_addAsyncConnectForSocket: _socket mode: runLoopMode delegate: self]; return; } [_socket of_closeSocket]; exception = [self of_connectionFailedExceptionForErrNo: errNo]; } inform_delegate: [self performSelector: @selector(of_socketDidConnect:exception:) withObject: _socket withObject: exception afterDelay: 0]; } - (void)of_socketDidConnect: (id)sock exception: (id)exception { id <OFSPXStreamSocketDelegate> delegate = ((OFSPXStreamSocket *)sock).delegate; if (exception == nil) ((OFSPXStreamSocket *)sock).canBlock = true; #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(exception); else { #endif if ([delegate respondsToSelector: @selector(socket:didConnectToNode:network:port:exception:)]) [delegate socket: _socket didConnectToNode: _node network: _network port: _port exception: exception]; #ifdef OF_HAVE_BLOCKS } #endif } - (id)of_connectionFailedExceptionForErrNo: (int)errNo { return [OFConnectionFailedException exceptionWithNode: _node network: _network port: _port socket: _socket errNo: errNo]; } @end @implementation OFSPXStreamSocket @dynamic delegate; - (int)of_createSocketForAddress: (const of_socket_address_t *)address errNo: (int *)errNo { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_socket = socket(address->sockaddr.ipx.sipx_family, SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET) { *errNo = of_socket_errno(); return false; } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif return true; } - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (connect(_socket, &address->sockaddr.sockaddr, address->length) != 0) { *errNo = of_socket_errno(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = INVALID_SOCKET; } - (void)connectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { of_socket_address_t address = of_socket_address_ipx(node, network, port); int errNo; if (![self of_createSocketForAddress: &address errNo: &errNo]) @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; if (![self of_connectSocketToAddress: &address errNo: &errNo]) { [self of_closeSocket]; @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; } } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { [self asyncConnectToNode: node network: network port: port runLoopMode: of_run_loop_mode_default]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXStreamSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port #ifdef OF_HAVE_BLOCKS block: NULL #endif ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (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 { [self asyncConnectToNode: node network: network port: port runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_spx_stream_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXStreamSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port block: block ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (of_socket_address_t)bindToPort: (uint16_t)port { const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; of_socket_address_t address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = of_socket_address_ipx(zeroNode, 0, port); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET) @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: of_socket_errno()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OF_SOCKET_ADDRESS_FAMILY_IPX; address.length = (socklen_t)sizeof(address.sockaddr); if (of_getsockname(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family != AF_IPX) { closesocket(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithPort: port packetType: SPX_PACKET_TYPE socket: self errNo: EAFNOSUPPORT]; } return address; } @end |
Modified src/OFSecureData.h from [994e2ce1cc] to [1f5cbd3690].
︙ | ︙ | |||
23 24 25 26 27 28 29 | * @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. * * @warning Non-swappable memory might be unavailable, in which case this falls * back to swappable memory, but still wipes the data when it gets | | | > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | * @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. * * @warning Non-swappable memory might be unavailable, in which case this falls * back to swappable memory, but still wipes the data when it gets * deallocated. Check the @ref allowsSwappableMemory property to see * whether a particular OFSecureData might be allocated in swappable * memory. */ OF_SUBCLASSING_RESTRICTED @interface OFSecureData: OFData { struct page *_page; bool _allowsSwappableMemory; } |
︙ | ︙ |
Added src/OFSequencedPacketSocket+Private.h version [a194b9d55d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFSequencedPacketSocket.h" OF_ASSUME_NONNULL_BEGIN @interface OFSequencedPacketSocket () #ifndef OF_WII @property (readonly, nonatomic) int of_socketError; #endif @end OF_ASSUME_NONNULL_END |
Added src/OFSequencedPacketSocket.h version [92ebbc1deb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFKernelEventObserver.h" #import "OFRunLoop.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @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 * @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 * @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 * @return A bool whether the same block should be used for the next incoming * connection */ 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 <OFObject> @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 * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (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 * @return The data to repeat the send with or nil if it should not repeat */ - (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 * success * @return A bool whether to accept the next incoming connection */ - (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. * * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFSequencedPacketSocket: OFObject <OFCopying, OFReadyForReadingObserving, OFReadyForWritingObserving> { of_socket_t _socket; bool _canBlock, _listening; of_socket_address_t _remoteAddress; id _Nullable _delegate; OF_RESERVE_IVARS(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 <OFSequencedPacketSocketDelegate> 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 * @param length The length of the buffer * @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. * * @param buffer The buffer to write the packet to * @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. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive */ - (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. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @param block The block to call when the packet has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more packets have been received. * If you want the next method in the queue to handle the packet * received next, you need to return false from the method. */ - (void) 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. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive * @param block The block to call when the packet has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more packets have been received. * If you want the next method in the queue to handle the packet * received next, you need to return false from the method. */ - (void) asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length 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 * if it should not repeat. */ - (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 * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data 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 * by the specified block as well. */ - (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 |
Added src/OFSequencedPacketSocket.m version [395d4dcdd4].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <assert.h> #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFSequencedPacketSocket.h" #import "OFSequencedPacketSocket+Private.h" #import "OFData.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #import "OFAcceptFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFListenFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" #import "socket.h" #import "socket_helpers.h" @implementation OFSequencedPacketSocket @synthesize listening = _listening, delegate = _delegate; + (void)initialize { if (self != [OFSequencedPacketSocket class]) return; if (!of_socket_init()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; @try { if (self.class == [OFSequencedPacketSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _socket = INVALID_SOCKET; _canBlock = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket != INVALID_SOCKET) [self close]; [super dealloc]; } #ifndef OF_WII - (int)of_socketError { int errNo; socklen_t len = sizeof(errNo); if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&errNo, &len) != 0) return of_socket_errno(); return errNo; } #endif - (id)copy { return [self retain]; } - (bool)canBlock { return _canBlock; } - (void)setCanBlock: (bool)canBlock { #if defined(HAVE_FCNTL) int flags = fcntl(_socket, F_GETFL, 0); if (flags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; if (canBlock) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(_socket, F_SETFL, flags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; _canBlock = canBlock; #elif defined(OF_WINDOWS) u_long v = canBlock; if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; _canBlock = canBlock; #else OF_UNRECOGNIZED_SELECTOR #endif } - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS if ((ret = recv(_socket, buffer, length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recv(_socket, buffer, (int)length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #endif return ret; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: of_run_loop_mode_default]; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncReceiveForSequencedPacketSocket: self buffer: buffer length: length mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void) asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (of_sequenced_packet_socket_async_receive_block_t) block { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: of_run_loop_mode_default block: block]; } - (void) asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sequenced_packet_socket_async_receive_block_t) block { [OFRunLoop of_addAsyncReceiveForSequencedPacketSocket: self buffer: buffer length: length mode: runLoopMode block: block delegate: nil]; } #endif - (void)sendBuffer: (const void *)buffer length: (size_t)length { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS ssize_t bytesWritten; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = send(_socket, (void *)buffer, length, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: of_socket_errno()]; #else int bytesWritten; if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = send(_socket, buffer, (int)length, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: of_socket_errno()]; #endif if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)asyncSendData: (OFData *)data { [self asyncSendData: data runLoopMode: of_run_loop_mode_default]; } - (void)asyncSendData: (OFData *)data runLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncSendForSequencedPacketSocket: self data: data mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncSendData: (OFData *)data block: (of_sequenced_packet_socket_async_send_data_block_t)block { [self asyncSendData: data runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncSendData: (OFData *)data runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sequenced_packet_socket_async_send_data_block_t)block { [OFRunLoop of_addAsyncSendForSequencedPacketSocket: self data: data mode: runLoopMode block: block delegate: nil]; } #endif - (void)listen { [self listenWithBacklog: SOMAXCONN]; } - (void)listenWithBacklog: (int)backlog { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (listen(_socket, backlog) == -1) @throw [OFListenFailedException exceptionWithSocket: self backlog: backlog errNo: of_socket_errno()]; _listening = true; } - (instancetype)accept { OFSequencedPacketSocket *client = [[[[self class] alloc] init] autorelease]; #if (!defined(HAVE_PACCEPT) && !defined(HAVE_ACCEPT4)) || !defined(SOCK_CLOEXEC) # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; # endif #endif client->_remoteAddress.length = (socklen_t)sizeof(client->_remoteAddress.sockaddr); #if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC) if ((client->_socket = paccept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) == INVALID_SOCKET) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: of_socket_errno()]; #elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if ((client->_socket = accept4(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, SOCK_CLOEXEC)) == INVALID_SOCKET) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: of_socket_errno()]; #else if ((client->_socket = accept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length)) == INVALID_SOCKET) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: of_socket_errno()]; # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1) fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC); # endif #endif assert(client->_remoteAddress.length <= (socklen_t)sizeof(client->_remoteAddress.sockaddr)); switch (client->_remoteAddress.sockaddr.sockaddr.sa_family) { case AF_INET: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_IPV4; break; #ifdef OF_HAVE_IPV6 case AF_INET6: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_IPV6; break; #endif #ifdef OF_HAVE_IPX case AF_IPX: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_IPX; break; #endif default: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_UNKNOWN; break; } return client; } - (void)asyncAccept { [self asyncAcceptWithRunLoopMode: of_run_loop_mode_default]; } - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: NULL delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncAcceptWithBlock: (of_sequenced_packet_socket_async_accept_block_t) block { [self asyncAcceptWithRunLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_sequenced_packet_socket_async_accept_block_t)block { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: block delegate: nil]; } #endif - (const of_socket_address_t *)remoteAddress { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (_remoteAddress.length == 0) @throw [OFInvalidArgumentException exception]; if (_remoteAddress.length > (socklen_t)sizeof(_remoteAddress.sockaddr)) @throw [OFOutOfRangeException exception]; return &_remoteAddress; } - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self mode: of_run_loop_mode_default]; } - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket; #else if (_socket == INVALID_SOCKET) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (int)fileDescriptorForWriting { #ifndef OF_WINDOWS return _socket; #else if (_socket == INVALID_SOCKET) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (void)close { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; _listening = false; memset(&_remoteAddress, 0, sizeof(_remoteAddress)); closesocket(_socket); _socket = INVALID_SOCKET; } @end |
Modified src/OFStdIOStream.h from [3916cd29d8] to [4b738f8353].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #ifdef OF_AMIGAOS # include <dos/dos.h> #endif OF_ASSUME_NONNULL_BEGIN /*! * @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 * instances of this class and need no initialization. | > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #ifdef OF_AMIGAOS # include <dos/dos.h> #endif OF_ASSUME_NONNULL_BEGIN /*! @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 * instances of this class and need no initialization. |
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #else BPTR _handle; bool _closable; #endif bool _atEndOfStream; } /*! * @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; @end #ifdef __cplusplus extern "C" { #endif /*! @file */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #else BPTR _handle; 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 */ - (void)setRelativeCursorPosition: (of_point_t)position; @end #ifdef __cplusplus extern "C" { #endif /*! @file */ |
︙ | ︙ | |||
80 81 82 83 84 85 86 | extern OFStdIOStream *_Nullable of_stdout; /*! * @brief The standard error as an OFStream. */ extern OFStdIOStream *_Nullable of_stderr; | > > > > > > | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | extern OFStdIOStream *_Nullable of_stdout; /*! * @brief The standard error as an OFStream. */ extern OFStdIOStream *_Nullable of_stderr; /*! * @brief Log 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. */ extern void of_log(OFConstantString *format, ...); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFStdIOStream.m from [730550a384] to [26a72da19c].
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #endif #ifdef HAVE_SYS_TTYCOM_H # include <sys/ttycom.h> #endif #import "OFStdIOStream.h" #import "OFStdIOStream+Private.h" #import "OFDate.h" #import "OFApplication.h" #ifdef OF_WINDOWS # include "OFWin32ConsoleStdIOStream.h" #endif #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifdef OF_AMIGAOS # include <proto/exec.h> | > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #endif #ifdef HAVE_SYS_TTYCOM_H # include <sys/ttycom.h> #endif #import "OFStdIOStream.h" #import "OFStdIOStream+Private.h" #import "OFColor.h" #import "OFDate.h" #import "OFApplication.h" #ifdef OF_WINDOWS # include "OFWin32ConsoleStdIOStream.h" #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifdef OF_AMIGAOS # include <proto/exec.h> |
︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 | va_end(arguments); [of_stderr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString, date.microsecond / 1000, me, getpid(), msg]; objc_autoreleasePoolPop(pool); } @implementation OFStdIOStream #ifndef OF_WINDOWS + (void)load { if (self != [OFStdIOStream class]) return; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | va_end(arguments); [of_stderr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString, date.microsecond / 1000, me, getpid(), msg]; objc_autoreleasePoolPop(pool); } #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) static int colorToANSI(OFColor *color) { if ([color isEqual: [OFColor black]]) return 30; if ([color isEqual: [OFColor maroon]]) return 31; if ([color isEqual: [OFColor green]]) return 32; if ([color isEqual: [OFColor olive]]) return 33; if ([color isEqual: [OFColor navy]]) return 34; if ([color isEqual: [OFColor purple]]) return 35; if ([color isEqual: [OFColor teal]]) return 36; if ([color isEqual: [OFColor silver]]) return 37; if ([color isEqual: [OFColor grey]]) return 90; if ([color isEqual: [OFColor red]]) return 91; if ([color isEqual: [OFColor lime]]) return 92; if ([color isEqual: [OFColor yellow]]) return 93; if ([color isEqual: [OFColor blue]]) return 94; if ([color isEqual: [OFColor fuchsia]]) return 95; if ([color isEqual: [OFColor aqua]]) return 96; if ([color isEqual: [OFColor white]]) return 97; return -1; } #endif @implementation OFStdIOStream #ifndef OF_WINDOWS + (void)load { if (self != [OFStdIOStream class]) return; |
︙ | ︙ | |||
338 339 340 341 342 343 344 345 346 347 348 349 350 351 | { } - (unsigned int)retainCount { return OF_RETAIN_COUNT_MAX; } - (int)columns { #if defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ) && !defined(OF_AMIGAOS) struct winsize ws; if (ioctl(_fd, TIOCGWINSZ, &ws) != 0) | > > > > > > > > > | 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | { } - (unsigned int)retainCount { return OF_RETAIN_COUNT_MAX; } - (bool)hasTerminal { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) return isatty(_fd); #else return false; #endif } - (int)columns { #if defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ) && !defined(OF_AMIGAOS) struct winsize ws; if (ioctl(_fd, TIOCGWINSZ, &ws) != 0) |
︙ | ︙ | |||
366 367 368 369 370 371 372 373 | return -1; return ws.ws_row; #else return -1; #endif } @end | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | return -1; return ws.ws_row; #else return -1; #endif } - (void)setForegroundColor: (OFColor *)color { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) int code; if (!isatty(_fd)) return; if ((code = colorToANSI(color)) == -1) return; [self writeFormat: @"\033[%um", code]; #endif } - (void)setBackgroundColor: (OFColor *)color { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) int code; if (!isatty(_fd)) return; if ((code = colorToANSI(color)) == -1) return; [self writeFormat: @"\033[%um", code + 10]; #endif } - (void)reset { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) if (!isatty(_fd)) return; [self writeString: @"\033[0m"]; #endif } - (void)clear { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) if (!isatty(_fd)) return; [self writeString: @"\033[2J"]; #endif } - (void)eraseLine { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) if (!isatty(_fd)) return; [self writeString: @"\033[2K"]; #endif } - (void)setCursorColumn: (unsigned int)column { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) if (!isatty(_fd)) return; [self writeFormat: @"\033[%uG", column + 1]; #endif } - (void)setCursorPosition: (of_point_t)position { if (position.x < 0 || position.y < 0) @throw [OFInvalidArgumentException exception]; #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) if (!isatty(_fd)) return; [self writeFormat: @"\033[%u;%uH", (unsigned)position.y + 1, (unsigned)position.x + 1]; #endif } - (void)setRelativeCursorPosition: (of_point_t)position { #if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) if (!isatty(_fd)) return; if (position.x > 0) [self writeFormat: @"\033[%uC", (unsigned)position.x]; else if (position.x < 0) [self writeFormat: @"\033[%uD", (unsigned)-position.x]; if (position.y > 0) [self writeFormat: @"\033[%uB", (unsigned)position.y]; else if (position.y < 0) [self writeFormat: @"\033[%uA", (unsigned)-position.y]; #endif } @end |
Modified src/OFStream.h from [7421ae1300] to [cac7e1c78f].
︙ | ︙ | |||
39 40 41 42 43 44 45 | @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. * | < < | | < | | < | < < | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | @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 * success * @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 * @param exception An exception which occurred while reading or `nil` on * success * @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 * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @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 * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @return The string to repeat the write with or nil if it should not repeat */ 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. */ |
︙ | ︙ | |||
192 193 194 195 196 197 198 | * the methods that do the actual work. OFStream uses those for all other * methods and does all the caching and other stuff for you. If you * override these methods without the `lowlevel` prefix, you *will* break * caching and get broken results! */ @interface OFStream: OFObject <OFCopying> { | | | | | | | | | | > > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | * the methods that do the actual work. OFStream uses those for all other * methods and does all the caching and other stuff for you. If you * override these methods without the `lowlevel` prefix, you *will* break * caching and get broken results! */ @interface OFStream: OFObject <OFCopying> { bool _canBlock; id _Nullable _delegate; #ifndef OF_SEEKABLE_STREAM_M @private #endif char *_Nullable _readBuffer, *_Nullable _readBufferMemory; char *_Nullable _writeBuffer; size_t _readBufferLength, _writeBufferLength; bool _buffersWrites, _waitingForDelimiter; OF_RESERVE_IVARS(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 <OFStreamDelegate> 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 - * this does not necessarily mean that the stream ended, so you still need to * check @ref atEndOfStream. Do not assume that the stream ended just because a * read returned 0 bytes - some streams do internal processing that has a * result of 0 bytes. * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! * @return The number of bytes read */ - (size_t)readIntoBuffer: (void *)buffer |
︙ | ︙ | |||
280 281 282 283 284 285 286 | * @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 * @ref asyncReadIntoBuffer:exactLength:. Note that a read can even return 0 * bytes - this does not necessarily mean that the stream ended, so you still | | > > | > > | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | * @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 * @ref asyncReadIntoBuffer:exactLength:. Note that a read can even return 0 * bytes - this does not necessarily mean that the stream ended, so you still * need to check @ref atEndOfStream. Do not assume that the stream ended just * because a read returned 0 bytes - some streams do internal processing that * has a result of 0 bytes. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * 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 * @ref asyncReadIntoBuffer:exactLength:. Note that a read can even return 0 * bytes - this does not necessarily mean that the stream ended, so you still * need to check @ref atEndOfStream. Do not assume that the stream ended just * because a read returned 0 bytes - some streams do internal processing that * has a result of 0 bytes. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. |
︙ | ︙ | |||
365 366 367 368 369 370 371 | * @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 * @ref asyncReadIntoBuffer:exactLength:block:. Note that a read can even * return 0 bytes - this does not necessarily mean that the stream ended, so | | > > | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | * @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 * @ref asyncReadIntoBuffer:exactLength:block:. Note that a read can even * return 0 bytes - this does not necessarily mean that the stream ended, so * you still need to check @ref atEndOfStream. Do not assume that the stream * ended just because a read returned 0 bytes - some streams do internal * processing that has a result of 0 bytes. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. |
︙ | ︙ | |||
392 393 394 395 396 397 398 | * @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 * @ref asyncReadIntoBuffer:exactLength:block:. Note that a read can even * return 0 bytes - this does not necessarily mean that the stream ended, so | | > > | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | * @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 * @ref asyncReadIntoBuffer:exactLength:block:. Note that a read can even * return 0 bytes - this does not necessarily mean that the stream ended, so * you still need to check @ref atEndOfStream. Do not assume that the stream * ended just because a read returned 0 bytes - some streams do internal * processing that has a result of 0 bytes. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. |
︙ | ︙ |
Modified src/OFStream.m from [749b5fd798] to [dd10e2b21b].
︙ | ︙ | |||
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #import "OFWriteFailedException.h" #import "of_asprintf.h" #define MIN_READ_SIZE 512 @implementation OFStream @synthesize of_waitingForDelimiter = _waitingForDelimiter, delegate = _delegate; #if defined(SIGPIPE) && defined(SIG_IGN) + (void)initialize { if (self == [OFStream class]) signal(SIGPIPE, SIG_IGN); } #endif - (instancetype)init { | > > | | > > > > | | | | < < < < < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | #import "OFWriteFailedException.h" #import "of_asprintf.h" #define MIN_READ_SIZE 512 @implementation OFStream @synthesize buffersWrites = _buffersWrites; @synthesize of_waitingForDelimiter = _waitingForDelimiter, delegate = _delegate; #if defined(SIGPIPE) && defined(SIG_IGN) + (void)initialize { if (self == [OFStream class]) signal(SIGPIPE, SIG_IGN); } #endif - (instancetype)init { self = [super init]; @try { if (self.class == [OFStream class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _canBlock = true; } @catch (id e) { [self release]; @throw e; } return self; } - (bool)lowlevelIsAtEndOfStream { OF_UNRECOGNIZED_SELECTOR |
︙ | ︙ | |||
1124 1125 1126 1127 1128 1129 1130 | - (OFString *)tryReadTillDelimiter: (OFString *)delimiter { return [self tryReadTillDelimiter: delimiter encoding: OF_STRING_ENCODING_UTF_8]; } | < < < < < < < < < < | | | 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 | - (OFString *)tryReadTillDelimiter: (OFString *)delimiter { return [self tryReadTillDelimiter: delimiter encoding: OF_STRING_ENCODING_UTF_8]; } - (void)flushWriteBuffer { if (_writeBuffer == NULL) return; [self lowlevelWriteBuffer: _writeBuffer length: _writeBufferLength]; [self freeMemory: _writeBuffer]; _writeBuffer = NULL; _writeBufferLength = 0; } - (size_t)writeBuffer: (const void *)buffer length: (size_t)length { if (!_buffersWrites) { size_t bytesWritten = [self lowlevelWriteBuffer: buffer length: length]; if (_canBlock && bytesWritten < length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; return bytesWritten; |
︙ | ︙ | |||
1796 1797 1798 1799 1800 1801 1802 | } - (bool)hasDataInReadBuffer { return (_readBufferLength > 0); } | | | | | | 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | } - (bool)hasDataInReadBuffer { return (_readBufferLength > 0); } - (bool)canBlock { return _canBlock; } - (void)setCanBlock: (bool)canBlock { #if defined(HAVE_FCNTL) && !defined(OF_AMIGAOS) bool readImplemented = false, writeImplemented = false; @try { int readFlags; readFlags = fcntl(((id <OFReadyForReadingObserving>)self) .fileDescriptorForReading, F_GETFL, 0); readImplemented = true; if (readFlags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; if (canBlock) readFlags &= ~O_NONBLOCK; else readFlags |= O_NONBLOCK; if (fcntl(((id <OFReadyForReadingObserving>)self) .fileDescriptorForReading, F_SETFL, readFlags) == -1) @throw [OFSetOptionFailedException |
︙ | ︙ | |||
1845 1846 1847 1848 1849 1850 1851 | writeImplemented = true; if (writeFlags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; | | | | 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 | writeImplemented = true; if (writeFlags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; if (canBlock) writeFlags &= ~O_NONBLOCK; else writeFlags |= O_NONBLOCK; if (fcntl(((id <OFReadyForWritingObserving>)self) .fileDescriptorForWriting, F_SETFL, writeFlags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; } @catch (OFNotImplementedException *e) { } if (!readImplemented && !writeImplemented) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; _canBlock = canBlock; #else OF_UNRECOGNIZED_SELECTOR #endif } - (int)fileDescriptorForReading { |
︙ | ︙ | |||
1912 1913 1914 1915 1916 1917 1918 | [self freeMemory: _readBufferMemory]; _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; [self freeMemory: _writeBuffer]; _writeBuffer = NULL; _writeBufferLength = 0; | | | 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 | [self freeMemory: _readBufferMemory]; _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; [self freeMemory: _writeBuffer]; _writeBuffer = NULL; _writeBufferLength = 0; _buffersWrites = false; _waitingForDelimiter = false; } @end |
Added src/OFStreamSocket+Private.h version [c1cf7136f2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFStreamSocket.h" OF_ASSUME_NONNULL_BEGIN @interface OFStreamSocket () #ifndef OF_WII @property (readonly, nonatomic) int of_socketError; #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFStreamSocket.h from [2284f227d5] to [ded40b41a4].
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #import "OFStream.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! * @class OFStreamSocket OFStreamSocket.h ObjFW/OFStreamSocket.h * * @brief A class which provides methods to create and use stream sockets. */ @interface OFStreamSocket: OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> { of_socket_t _socket; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | #import "OFStream.h" #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @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 * @return A bool whether the same block should be used for the next incoming * connection */ 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 <OFStreamDelegate> @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 * success * @return A bool whether to accept the next incoming connection */ - (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 <OFReadyForReadingObserving, OFReadyForWritingObserving> { of_socket_t _socket; bool _atEndOfStream, _listening; of_socket_address_t _remoteAddress; OF_RESERVE_IVARS(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 <OFStreamSocketDelegate> 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 * by the specified block as well. */ - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_socket_async_accept_block_t) block; #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFStreamSocket.m from [bc21bce60d] to [2df2daa037].
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | * file. */ #define __NO_EXT_QNX #include "config.h" #include <errno.h> #include <string.h> #import "OFStreamSocket.h" #import "OFInitializationFailedException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" #import "socket_helpers.h" @implementation OFStreamSocket + (void)initialize { if (self != [OFStreamSocket class]) return; if (!of_socket_init()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (bool)lowlevelIsAtEndOfStream { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | * file. */ #define __NO_EXT_QNX #include "config.h" #include <assert.h> #include <errno.h> #include <string.h> #import "OFStreamSocket.h" #import "OFStreamSocket+Private.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFAcceptFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFListenFailedException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" #import "socket_helpers.h" @implementation OFStreamSocket @dynamic delegate; @synthesize listening = _listening; + (void)initialize { if (self != [OFStreamSocket class]) return; if (!of_socket_init()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; @try { if (self.class == [OFStreamSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _socket = INVALID_SOCKET; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket != INVALID_SOCKET) [self close]; [super dealloc]; } - (bool)lowlevelIsAtEndOfStream { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; |
︙ | ︙ | |||
69 70 71 72 73 74 75 | #ifndef OF_WINDOWS if ((ret = recv(_socket, buffer, length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #else | | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | #ifndef OF_WINDOWS if ((ret = recv(_socket, buffer, length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recv(_socket, buffer, (int)length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #endif if (ret == 0) |
︙ | ︙ | |||
121 122 123 124 125 126 127 | errNo: of_socket_errno()]; #endif return (size_t)bytesWritten; } #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) | | | | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | errNo: of_socket_errno()]; #endif return (size_t)bytesWritten; } #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) - (void)setCanBlock: (bool)canBlock { # ifdef OF_WINDOWS u_long v = canBlock; # else char v = canBlock; # endif if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; _canBlock = canBlock; } #endif - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket; |
︙ | ︙ | |||
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (void)close { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; closesocket(_socket); _socket = INVALID_SOCKET; _atEndOfStream = false; [super close]; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } #ifndef OF_WII - (int)of_socketError { int errNo; socklen_t len = sizeof(errNo); if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&errNo, &len) != 0) return of_socket_errno(); return errNo; } #endif - (void)listen { [self listenWithBacklog: SOMAXCONN]; } - (void)listenWithBacklog: (int)backlog { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (listen(_socket, backlog) == -1) @throw [OFListenFailedException exceptionWithSocket: self backlog: backlog errNo: of_socket_errno()]; _listening = true; } - (instancetype)accept { OFStreamSocket *client = [[[[self class] alloc] init] autorelease]; #if (!defined(HAVE_PACCEPT) && !defined(HAVE_ACCEPT4)) || !defined(SOCK_CLOEXEC) # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; # endif #endif client->_remoteAddress.length = (socklen_t)sizeof(client->_remoteAddress.sockaddr); #if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC) if ((client->_socket = paccept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) == INVALID_SOCKET) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: of_socket_errno()]; #elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if ((client->_socket = accept4(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, SOCK_CLOEXEC)) == INVALID_SOCKET) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: of_socket_errno()]; #else if ((client->_socket = accept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length)) == INVALID_SOCKET) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: of_socket_errno()]; # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1) fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC); # endif #endif assert(client->_remoteAddress.length <= (socklen_t)sizeof(client->_remoteAddress.sockaddr)); switch (client->_remoteAddress.sockaddr.sockaddr.sa_family) { case AF_INET: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_IPV4; break; #ifdef OF_HAVE_IPV6 case AF_INET6: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_IPV6; break; #endif #ifdef OF_HAVE_IPX case AF_IPX: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_IPX; break; #endif default: client->_remoteAddress.family = OF_SOCKET_ADDRESS_FAMILY_UNKNOWN; break; } return client; } - (void)asyncAccept { [self asyncAcceptWithRunLoopMode: of_run_loop_mode_default]; } - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: NULL delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncAcceptWithBlock: (of_stream_socket_async_accept_block_t)block { [self asyncAcceptWithRunLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncAcceptWithRunLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_stream_socket_async_accept_block_t)block { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: block delegate: nil]; } #endif - (const of_socket_address_t *)remoteAddress { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (_remoteAddress.length == 0) @throw [OFInvalidArgumentException exception]; if (_remoteAddress.length > (socklen_t)sizeof(_remoteAddress.sockaddr)) @throw [OFOutOfRangeException exception]; return &_remoteAddress; } - (void)close { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; _listening = false; memset(&_remoteAddress, 0, sizeof(_remoteAddress)); closesocket(_socket); _socket = INVALID_SOCKET; _atEndOfStream = false; [super close]; } @end |
Modified src/OFString.h from [dae29d5404] to [18fc9bbd71].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * 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. */ #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif | > > > | | > | | | > > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | * 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. */ #ifndef OBJFW_OF_STRING_H #define OBJFW_OF_STRING_H #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include "objfw-defs.h" #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #include <stdarg.h> #include <stdint.h> #ifdef OF_HAVE_INTTYPES_H # include <inttypes.h> #endif #include "OFObject.h" #ifdef __OBJC__ # import "OFSerialization.h" # import "OFJSONRepresentation.h" # import "OFMessagePackRepresentation.h" #endif OF_ASSUME_NONNULL_BEGIN /*! @file */ #ifdef __OBJC__ @class OFConstantString; @class OFString; #else typedef void OFString; #endif #if defined(__cplusplus) && __cplusplus >= 201103L typedef char16_t of_char16_t; typedef char32_t of_char32_t; #else typedef uint_least16_t of_char16_t; typedef uint_least32_t of_char32_t; |
︙ | ︙ | |||
106 107 108 109 110 111 112 113 114 115 116 117 118 119 | * @param line The current line * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^of_string_line_enumeration_block_t)(OFString *line, bool *stop); #endif @class OFArray OF_GENERIC(ObjectType); @class OFCharacterSet; @class OFURL; /*! * @class OFString OFString.h ObjFW/OFString.h * | > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | * @param line The current line * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^of_string_line_enumeration_block_t)(OFString *line, bool *stop); #endif #ifdef __OBJC__ @class OFArray OF_GENERIC(ObjectType); @class OFCharacterSet; @class OFURL; /*! * @class OFString OFString.h ObjFW/OFString.h * |
︙ | ︙ | |||
161 162 163 164 165 166 167 | /*! * @brief The decimal value of the string as an `intmax_t`. * * Leading and trailing whitespaces are ignored. * * If the string contains any non-number characters, an | | | | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | /*! * @brief The decimal value of the string as an `intmax_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 `intmax_t`, an * @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) intmax_t decimalValue; /*! * @brief The hexadecimal 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 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; /*! * @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 |
︙ | ︙ | |||
260 261 262 263 264 265 266 | @property (readonly, nonatomic) OFString *stringByDeletingTrailingWhitespaces; /*! * @brief The string with leading and trailing whitespaces deleted. */ @property (readonly, nonatomic) OFString *stringByDeletingEnclosingWhitespaces; | | | > > > > > > > > | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | @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; |
︙ | ︙ | |||
487 488 489 490 491 492 493 | * `const of_unichar_t *`. * * @param format A string used as format to initialize the OFString * @return A new autoreleased OFString */ + (instancetype)stringWithFormat: (OFConstantString *)format, ...; | | | | | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | * `const of_unichar_t *`. * * @param format A string used as format to initialize the OFString * @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 * @return A new autoreleased OFString */ + (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 * headers. If it could not detect the encoding using the HTTP headers, it tries |
︙ | ︙ | |||
534 535 536 537 538 539 540 | * * @param URL The URL to the contents for the string * @param encoding The encoding to assume * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding; | | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | * * @param URL The URL to the contents for the string * @param encoding The encoding to assume * @return A new autoreleased OFString */ + (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 |
︙ | ︙ | |||
761 762 763 764 765 766 767 | * @param format A string used as format to initialize the OFString * @param arguments The arguments used in the format string * @return An initialized OFString */ - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments; | | | | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | * @param format A string used as format to initialize the OFString * @param arguments The arguments used in the format string * @return An initialized OFString */ - (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 * @return An initialized OFString */ - (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. * |
︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | * @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; | | | | | > | | > | | | | | | | | | | > | > > | 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 | * @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 */ - (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; # endif @end #endif #ifdef __cplusplus extern "C" { #endif extern of_string_encoding_t of_string_parse_encoding(OFString *); extern OFString *_Nullable of_string_name_of_encoding(of_string_encoding_t); extern size_t of_string_utf8_encode(of_unichar_t, char *); extern ssize_t of_string_utf8_decode(const char *, size_t, of_unichar_t *); extern size_t of_string_utf16_length(const of_char16_t *); extern size_t of_string_utf32_length(const of_char32_t *); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #include "OFConstantString.h" #include "OFMutableString.h" #ifdef __OBJC__ # import "OFString+CryptoHashing.h" # import "OFString+JSONValue.h" # ifdef OF_HAVE_FILES # import "OFString+PathAdditions.h" # endif # import "OFString+PropertyListValue.h" # import "OFString+Serialization.h" # import "OFString+URLEncoding.h" # import "OFString+XMLEscaping.h" # import "OFString+XMLUnescaping.h" #endif #if defined(__OBJC__) && !defined(NSINTEGER_DEFINED) && !__has_feature(modules) /* * Very *ugly* hack required for string boxing literals to work. * * This hack is needed in order to work with `@class NSString` from Apple's * objc/NSString.h - which is included when using modules - as * @compatibility_alias does not work if @class has been used before. * For some reason, this makes Clang refer to OFString for string box literals * and not to NSString (which would result in a linker error, but would be the * correct behavior). * * TODO: Submit a patch for Clang that makes the boxing classes configurable! */ @interface NSString: OFString @end #endif #endif |
Modified src/OFString.m from [57dadde5e8] to [9bf92ef7e1].
︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFLocale.h" #import "OFStream.h" #import "OFURL.h" #import "OFURLHandler.h" #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" | > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFLocale.h" #import "OFStream.h" #import "OFSystemInfo.h" #import "OFURL.h" #import "OFURLHandler.h" #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" |
︙ | ︙ | |||
186 187 188 189 190 191 192 | else if ([string isEqual: @"macintosh"] || [string isEqual: @"mac"]) encoding = OF_STRING_ENCODING_MAC_ROMAN; else if ([string isEqual: @"koi8-r"]) encoding = OF_STRING_ENCODING_KOI8_R; else if ([string isEqual: @"koi8-u"]) encoding = OF_STRING_ENCODING_KOI8_U; else | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | else if ([string isEqual: @"macintosh"] || [string isEqual: @"mac"]) encoding = OF_STRING_ENCODING_MAC_ROMAN; else if ([string isEqual: @"koi8-r"]) encoding = OF_STRING_ENCODING_KOI8_R; else if ([string isEqual: @"koi8-u"]) encoding = OF_STRING_ENCODING_KOI8_U; else @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); return encoding; } OFString * |
︙ | ︙ | |||
2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 | OF_UNICODE_DECOMPOSITION_TABLE_SIZE); } - (OFString *)decomposedStringWithCompatibilityMapping { return decomposedString(self, of_unicode_decomposition_compat_table, OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE); } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self writeToFile: path | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 | OF_UNICODE_DECOMPOSITION_TABLE_SIZE); } - (OFString *)decomposedStringWithCompatibilityMapping { return decomposedString(self, of_unicode_decomposition_compat_table, OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE); } #endif #ifdef OF_WINDOWS - (OFString *)stringByExpandingWindowsEnvironmentStrings { if ([OFSystemInfo isWindowsNT]) { wchar_t buffer[512]; size_t length; if ((length = ExpandEnvironmentStringsW(self.UTF16String, buffer, sizeof(buffer))) == 0) return self; return [OFString stringWithUTF16String: buffer length: length - 1]; } else { of_string_encoding_t encoding = [OFLocale encoding]; char buffer[512]; size_t length; if ((length = ExpandEnvironmentStringsA( [self cStringWithEncoding: encoding], buffer, sizeof(buffer))) == 0) return self; return [OFString stringWithCString: buffer encoding: encoding length: length - 1]; } } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self writeToFile: path |
︙ | ︙ |
Modified src/OFSystemInfo.h from [3dbc07c33c] to [0a359fe12b].
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | @property (class, readonly, nonatomic) bool supportsAVX2; @property (class, readonly, nonatomic) bool supportsAESNI; @property (class, readonly, nonatomic) bool supportsSHAExtensions; # endif # if defined(OF_POWERPC) || defined(OF_POWERPC64) || defined(DOXYGEN) @property (class, readonly, nonatomic) bool supportsAltiVec; # endif #endif /*! * @brief Returns the size of a page. * * @return The size of a page */ | > > > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | @property (class, readonly, nonatomic) bool supportsAVX2; @property (class, readonly, nonatomic) bool supportsAESNI; @property (class, readonly, nonatomic) bool supportsSHAExtensions; # endif # if defined(OF_POWERPC) || defined(OF_POWERPC64) || defined(DOXYGEN) @property (class, readonly, nonatomic) bool supportsAltiVec; # endif # 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 */ |
︙ | ︙ | |||
282 283 284 285 286 287 288 289 290 291 292 293 294 | * * @note This method is only available on PowerPC and PowerPC 64. * * @return Whether the CPU and OS support AltiVec */ + (bool)supportsAltiVec; #endif + (instancetype)alloc OF_UNAVAILABLE; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | * * @note This method is only available on PowerPC and PowerPC 64. * * @return Whether the CPU and OS support AltiVec */ + (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 */ + (bool)isWindowsNT; #endif + (instancetype)alloc OF_UNAVAILABLE; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/OFSystemInfo.m from [7bac8e5add] to [0f92abda7c].
︙ | ︙ | |||
161 162 163 164 165 166 167 | } # endif #elif defined(OF_WINDOWS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { | > | | | | | | | | | | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | } # endif #elif defined(OF_WINDOWS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { of_string_encoding_t encoding = [OFLocale encoding]; char systemDir[PATH_MAX]; UINT systemDirLen; OFString *systemDirString; const char *path; void *buffer; DWORD bufferLen; systemDirLen = GetSystemDirectoryA(systemDir, PATH_MAX); if (systemDirLen == 0) return; systemDirString = [OFString stringWithCString: systemDir encoding: encoding length: systemDirLen]; path = [[systemDirString stringByAppendingPathComponent: @"kernel32.dll"] cStringWithEncoding: encoding]; if ((bufferLen = GetFileVersionInfoSizeA(path, NULL)) == 0) return; if ((buffer = malloc(bufferLen)) == 0) return; @try { void *data; UINT dataLen; VS_FIXEDFILEINFO *info; if (!GetFileVersionInfoA(path, 0, bufferLen, buffer)) return; if (!VerQueryValueA(buffer, "\\", &data, &dataLen) || dataLen < sizeof(info)) return; info = (VS_FIXEDFILEINFO *)data; operatingSystemVersion = [[OFString alloc] initWithFormat: @"%u.%u.%u", |
︙ | ︙ | |||
660 661 662 663 664 665 666 667 668 669 670 671 672 | SYSTEMINFOTYPE_PPC_ALTIVEC, TAG_DONE) > 0) return supportsAltiVec; # endif return false; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } @end | > > > > > > > | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | SYSTEMINFOTYPE_PPC_ALTIVEC, TAG_DONE) > 0) return supportsAltiVec; # endif return false; } #endif #ifdef OF_WINDOWS + (bool)isWindowsNT { return !(GetVersion() & 0x80000000); } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } @end |
Deleted src/OFTCPSocket+Private.h version [04e97a23b2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFTCPSocket.h from [e4fec95ad0] to [cedf99692f].
︙ | ︙ | |||
27 28 29 30 31 32 33 | @class OFTCPSocket; @class OFString; #ifdef OF_HAVE_BLOCKS /*! * @brief A block which is called when the socket connected. * | < | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | > | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | @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 <OFStreamSocketDelegate> @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 * @param exception An exception that occurred while connecting, or nil on * success */ - (void)socket: (OFTCPSocket *)socket 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. * To create a server, create a socket, bind it and listen on it. */ @interface OFTCPSocket: OFStreamSocket { OFString *_Nullable _SOCKS5Host; uint16_t _SOCKS5Port; #ifdef OF_WII uint16_t _port; #endif OF_RESERVE_IVARS(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 <OFTCPSocketDelegate> delegate; /*! * @brief Sets the global SOCKS5 proxy host to use when creating a new socket * |
︙ | ︙ | |||
252 253 254 255 256 257 258 | * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end #ifdef __cplusplus extern "C" { #endif extern Class _Nullable of_tls_socket_class; #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFTCPSocket.m from [6288b956d6] to [dc32b6d4c9].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * 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. */ | < < | | | | | | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | * * 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 __NO_EXT_QNX #include "config.h" #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFTCPSocket.h" #import "OFDNSResolver.h" #import "OFData.h" #import "OFDate.h" #import "OFIPSocketAsyncConnector.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFString.h" #import "OFTCPSocketSOCKS5Connector.h" #import "OFThread.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFGetOptionFailedException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFSetOptionFailedException.h" #import "socket.h" #import "socket_helpers.h" static const of_run_loop_mode_t connectRunLoopMode = @"of_tcp_socket_connect_mode"; Class of_tls_socket_class = Nil; static OFString *defaultSOCKS5Host = nil; static uint16_t defaultSOCKS5Port = 1080; @interface OFTCPSocket () <OFIPSocketAsyncConnecting> @end @interface OFTCPSocketConnectDelegate: OFObject <OFTCPSocketDelegate> { @public bool _done; id _exception; } @end @implementation OFTCPSocketConnectDelegate - (void)dealloc { [_exception release]; |
︙ | ︙ | |||
647 648 649 650 651 652 653 | } - (instancetype)init { self = [super init]; @try { | < | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | } - (instancetype)init { self = [super init]; @try { _SOCKS5Host = [defaultSOCKS5Host copy]; _SOCKS5Port = defaultSOCKS5Port; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; if (connect(_socket, (struct sockaddr *)&address->sockaddr.sockaddr, address->length) != 0) { *errNo = of_socket_errno(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = INVALID_SOCKET; } | > < < < < < < < < < < < < < < | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; /* Cast needed for AmigaOS, where the argument is declared non-const */ if (connect(_socket, (struct sockaddr *)&address->sockaddr.sockaddr, address->length) != 0) { *errNo = of_socket_errno(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = INVALID_SOCKET; } - (void)connectToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = _delegate; OFTCPSocketConnectDelegate *connectDelegate = [[[OFTCPSocketConnectDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; self.delegate = connectDelegate; [self asyncConnectToHost: host port: port |
︙ | ︙ | |||
767 768 769 770 771 772 773 774 | } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); | > > > > > > > > > > > > > > > > > > > | < < | > | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate; if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if (_SOCKS5Host != nil) { delegate = [[[OFTCPSocketSOCKS5Connector alloc] initWithSocket: self host: host port: port delegate: _delegate #ifdef OF_HAVE_BLOCKS block: NULL #endif ] autorelease]; host = _SOCKS5Host; port = _SOCKS5Port; } else delegate = _delegate; [[[[OFIPSocketAsyncConnector alloc] initWithSocket: self host: host port: port delegate: delegate block: NULL ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port |
︙ | ︙ | |||
797 798 799 800 801 802 803 804 | - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_tcp_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); | > > > > > > > > > > > > > > > | | < | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_tcp_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = nil; if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if (_SOCKS5Host != nil) { delegate = [[[OFTCPSocketSOCKS5Connector alloc] initWithSocket: self host: host port: port delegate: nil block: block] autorelease]; host = _SOCKS5Host; port = _SOCKS5Port; } [[[[OFIPSocketAsyncConnector alloc] initWithSocket: self host: host port: port delegate: delegate block: (delegate == nil ? block : NULL)] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (uint16_t)bindToHost: (OFString *)host |
︙ | ︙ | |||
844 845 846 847 848 849 850 | SOCK_STREAM | SOCK_CLOEXEC, 0)) == INVALID_SOCKET) @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: of_socket_errno()]; | | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | SOCK_STREAM | SOCK_CLOEXEC, 0)) == INVALID_SOCKET) @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: of_socket_errno()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, |
︙ | ︙ | |||
949 950 951 952 953 954 955 | @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: EADDRNOTAVAIL]; #endif } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | < < < < | 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: EADDRNOTAVAIL]; #endif } #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) - (void)setSendsKeepAlives: (bool)sendsKeepAlives { int v = sendsKeepAlives; if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; } - (bool)sendsKeepAlives { int v; socklen_t len = sizeof(v); if (getsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; return v; } #endif #ifndef OF_WII - (void)setCanDelaySendingSegments: (bool)canDelaySendingSegments { int v = !canDelaySendingSegments; if (setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; } - (bool)canDelaySendingSegments { int v; socklen_t len = sizeof(v); if (getsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: of_socket_errno()]; return !v; } #endif - (void)close { #ifdef OF_WII _port = 0; #endif [super close]; } @end |
Added src/OFTCPSocketSOCKS5Connector.h version [1461d18ce8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFTCPSocket.h" OF_ASSUME_NONNULL_BEGIN @class OFString; @interface OFTCPSocketSOCKS5Connector: OFObject <OFTCPSocketDelegate> { OFTCPSocket *_socket; OFString *_host; uint16_t _port; id <OFTCPSocketDelegate> _Nullable _delegate; #ifdef OF_HAVE_BLOCKS of_tcp_socket_async_connect_block_t _Nullable _block; #endif id _Nullable _exception; enum { OF_SOCKS5_STATE_SEND_AUTHENTICATION = 1, OF_SOCKS5_STATE_READ_VERSION, OF_SOCKS5_STATE_SEND_REQUEST, OF_SOCKS5_STATE_READ_RESPONSE, OF_SOCKS5_STATE_READ_ADDRESS, OF_SOCKS5_STATE_READ_ADDRESS_LENGTH, } _SOCKS5State; /* Longest read is domain name (max 255 bytes) + port */ unsigned char _buffer[257]; OFMutableData *_Nullable _request; } - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (nullable id <OFTCPSocketDelegate>)delegate #ifdef OF_HAVE_BLOCKS block: (nullable of_tcp_socket_async_connect_block_t) block #endif ; - (void)didConnect; @end OF_ASSUME_NONNULL_END |
Added src/OFTCPSocketSOCKS5Connector.m version [a4bbcb1257].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <assert.h> #include <errno.h> #import "OFTCPSocketSOCKS5Connector.h" #import "OFData.h" #import "OFRunLoop.h" #import "OFString.h" #import "OFConnectionFailedException.h" @implementation OFTCPSocketSOCKS5Connector - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (id <OFTCPSocketDelegate>)delegate #ifdef OF_HAVE_BLOCKS block: (of_tcp_socket_async_connect_block_t)block #endif { self = [super init]; @try { _socket = [sock retain]; _host = [host copy]; _port = port; _delegate = [delegate retain]; #ifdef OF_HAVE_BLOCKS _block = [block copy]; #endif _socket.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket.delegate == self) _socket.delegate = _delegate; [_socket release]; [_host release]; [_delegate release]; #ifdef OF_HAVE_BLOCKS [_block release]; #endif [_exception release]; [_request release]; [super dealloc]; } - (void)didConnect { _socket.delegate = _delegate; #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(_exception); else { #endif if ([_delegate respondsToSelector: @selector(socket:didConnectToHost:port:exception:)]) [_delegate socket: _socket didConnectToHost: _host port: _port exception: _exception]; #ifdef OF_HAVE_BLOCKS } #endif } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { OFData *data; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return; } data = [OFData dataWithItems: "\x05\x01\x00" count: 3]; _SOCKS5State = OF_SOCKS5_STATE_SEND_AUTHENTICATION; [_socket asyncWriteData: data runLoopMode: [OFRunLoop currentRunLoop].currentMode]; } - (bool)stream: (OFStream *)sock didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { of_run_loop_mode_t runLoopMode; unsigned char *SOCKSVersion; uint8_t hostLength; unsigned char port[2]; unsigned char *response, *addressLength; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return false; } runLoopMode = [OFRunLoop currentRunLoop].currentMode; switch (_SOCKS5State) { case OF_SOCKS5_STATE_READ_VERSION: SOCKSVersion = buffer; if (SOCKSVersion[0] != 5 || SOCKSVersion[1] != 0) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: self errNo: EPROTONOSUPPORT]; [self didConnect]; return false; } [_request release]; _request = [[OFMutableData alloc] init]; [_request addItems: "\x05\x01\x00\x03" count: 4]; hostLength = (uint8_t)_host.UTF8StringLength; [_request addItem: &hostLength]; [_request addItems: _host.UTF8String count: hostLength]; port[0] = _port >> 8; port[1] = _port & 0xFF; [_request addItems: port count: 2]; _SOCKS5State = OF_SOCKS5_STATE_SEND_REQUEST; [_socket asyncWriteData: _request runLoopMode: runLoopMode]; return false; case OF_SOCKS5_STATE_READ_RESPONSE: response = buffer; if (response[0] != 5 || response[2] != 0) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: self errNo: EPROTONOSUPPORT]; [self didConnect]; return false; } if (response[1] != 0) { int errNo; switch (response[1]) { case 0x02: errNo = EPERM; break; case 0x03: errNo = ENETUNREACH; break; case 0x04: errNo = EHOSTUNREACH; break; case 0x05: errNo = ECONNREFUSED; break; case 0x06: errNo = ETIMEDOUT; break; case 0x07: errNo = EOPNOTSUPP; break; case 0x08: errNo = EAFNOSUPPORT; break; default: #ifdef EPROTO errNo = EPROTO; #else errNo = 0; #endif break; } _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return false; } /* Skip the rest of the response */ switch (response[3]) { case 1: /* IPv4 */ _SOCKS5State = OF_SOCKS5_STATE_READ_ADDRESS; [_socket asyncReadIntoBuffer: _buffer exactLength: 4 + 2 runLoopMode: runLoopMode]; return false; case 3: /* Domain name */ _SOCKS5State = OF_SOCKS5_STATE_READ_ADDRESS_LENGTH; [_socket asyncReadIntoBuffer: _buffer exactLength: 1 runLoopMode: runLoopMode]; return false; case 4: /* IPv6 */ _SOCKS5State = OF_SOCKS5_STATE_READ_ADDRESS; [_socket asyncReadIntoBuffer: _buffer exactLength: 16 + 2 runLoopMode: runLoopMode]; return false; default: _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: self errNo: EPROTONOSUPPORT]; [self didConnect]; return false; } return false; case OF_SOCKS5_STATE_READ_ADDRESS: [self didConnect]; return false; case OF_SOCKS5_STATE_READ_ADDRESS_LENGTH: addressLength = buffer; _SOCKS5State = OF_SOCKS5_STATE_READ_ADDRESS; [_socket asyncReadIntoBuffer: _buffer exactLength: addressLength[0] + 2 runLoopMode: runLoopMode]; return false; default: assert(0); return false; } } - (OFData *)stream: (OFStream *)sock didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { of_run_loop_mode_t runLoopMode; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return nil; } runLoopMode = [OFRunLoop currentRunLoop].currentMode; switch (_SOCKS5State) { case OF_SOCKS5_STATE_SEND_AUTHENTICATION: _SOCKS5State = OF_SOCKS5_STATE_READ_VERSION; [_socket asyncReadIntoBuffer: _buffer exactLength: 2 runLoopMode: runLoopMode]; return nil; case OF_SOCKS5_STATE_SEND_REQUEST: [_request release]; _request = nil; _SOCKS5State = OF_SOCKS5_STATE_READ_RESPONSE; [_socket asyncReadIntoBuffer: _buffer exactLength: 4 runLoopMode: runLoopMode]; return nil; default: assert(0); return nil; } } @end |
Modified src/OFTLSSocket.h from [c867497861] to [ba822d3148].
︙ | ︙ | |||
77 78 79 80 81 82 83 | * @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; /*! | | | < | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | * @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 */ |
︙ | ︙ |
Modified src/OFTarArchive.m from [fe80dcdcf2] to [74012ab28d].
︙ | ︙ | |||
96 97 98 99 100 101 102 | _mode = OF_TAR_ARCHIVE_MODE_WRITE; else if ([mode isEqual: @"a"]) _mode = OF_TAR_ARCHIVE_MODE_APPEND; else @throw [OFInvalidArgumentException exception]; if (_mode == OF_TAR_ARCHIVE_MODE_APPEND) { | < < | < | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | _mode = OF_TAR_ARCHIVE_MODE_WRITE; else if ([mode isEqual: @"a"]) _mode = OF_TAR_ARCHIVE_MODE_APPEND; else @throw [OFInvalidArgumentException exception]; if (_mode == OF_TAR_ARCHIVE_MODE_APPEND) { uint32_t buffer[1024 / sizeof(uint32_t)]; bool empty = true; if (![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; [(OFSeekableStream *)_stream seekToOffset: -1024 whence: SEEK_END]; [_stream readIntoBuffer: buffer exactLength: 1024]; for (size_t i = 0; i < 1024 / sizeof(uint32_t); i++) if (buffer[i] != 0) empty = false; if (!empty) @throw [OFInvalidFormatException exception]; [(OFSeekableStream *)stream seekToOffset: -1024 whence: SEEK_END]; |
︙ | ︙ | |||
164 165 166 167 168 169 170 | [super dealloc]; } - (OFTarArchiveEntry *)nextEntry { OFTarArchiveEntry *entry; | < < | < | | | | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | [super dealloc]; } - (OFTarArchiveEntry *)nextEntry { OFTarArchiveEntry *entry; uint32_t buffer[512 / sizeof(uint32_t)]; bool empty = true; if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; [(OFTarArchiveFileReadStream *)_lastReturnedStream of_skip]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } [_lastReturnedStream release]; _lastReturnedStream = nil; if (_stream.atEndOfStream) return nil; [_stream readIntoBuffer: buffer exactLength: 512]; for (size_t i = 0; i < 512 / sizeof(uint32_t); i++) if (buffer[i] != 0) empty = false; if (empty) { [_stream readIntoBuffer: buffer exactLength: 512]; for (size_t i = 0; i < 512 / sizeof(uint32_t); i++) if (buffer[i] != 0) @throw [OFInvalidFormatException exception]; return nil; } entry = [[[OFTarArchiveEntry alloc] of_initWithHeader: (unsigned char *)buffer encoding: _encoding] autorelease]; _lastReturnedStream = [[OFTarArchiveFileReadStream alloc] of_initWithStream: _stream entry: entry]; return entry; |
︙ | ︙ | |||
500 501 502 503 504 505 506 | if (_toWrite > 0) @throw [OFTruncatedDataException exception]; remainder = 512 - _entry.size % 512; if (remainder != 512) { | | | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | if (_toWrite > 0) @throw [OFTruncatedDataException exception]; remainder = 512 - _entry.size % 512; if (remainder != 512) { bool didBufferWrites = _stream.buffersWrites; _stream.buffersWrites = true; while (remainder--) [_stream writeInt8: 0]; [_stream flushWriteBuffer]; _stream.buffersWrites = didBufferWrites; } [_stream release]; _stream = nil; [super close]; } @end |
Modified src/OFUDPSocket.h from [1854fff845] to [d9eb072d8d].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * 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. */ | | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * * 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 "OFDatagramSocket.h" OF_ASSUME_NONNULL_BEGIN @class OFString; /*! * @protocol OFUDPSocketDelegate OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A delegate for OFUDPSocket. */ @protocol OFUDPSocketDelegate <OFDatagramSocketDelegate> @end /*! * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A class which provides methods to create and use UDP sockets. * |
︙ | ︙ | |||
112 113 114 115 116 117 118 | * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ | | < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFUDPSocket: OFDatagramSocket { #ifdef OF_WII uint16_t _port; #endif OF_RESERVE_IVARS(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 <OFUDPSocketDelegate> 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 * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Modified src/OFUDPSocket.m from [c8408c9960] to [851b1788ef].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * 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" | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * 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 <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFUDPSocket.h" #import "OFUDPSocket+Private.h" #import "OFDNSResolver.h" #import "OFData.h" #import "OFThread.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "socket.h" #import "socket_helpers.h" @implementation OFUDPSocket @dynamic delegate; - (uint16_t)of_bindToAddress: (of_socket_address_t *)address extraType: (int)extraType { void *pool = objc_autoreleasePoolPush(); OFString *host; uint16_t port; |
︙ | ︙ | |||
142 143 144 145 146 147 148 | @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: of_socket_errno()]; } | | > | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: of_socket_errno()]; } _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) /* {} needed to avoid warning with Clang 10 if next #if is false. */ if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) { fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); } #endif #if defined(OF_WII) || defined(OF_NINTENDO_3DS) if (of_socket_address_get_port(address) != 0) { #endif if (bind(_socket, &address->sockaddr.sockaddr, address->length) != 0) { |
︙ | ︙ | |||
275 276 277 278 279 280 281 | port = [self of_bindToAddress: &address extraType: 0]; objc_autoreleasePoolPop(pool); return port; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 189 190 191 192 193 194 195 196 | port = [self of_bindToAddress: &address extraType: 0]; objc_autoreleasePoolPop(pool); return port; } @end |
Modified src/OFURL.m from [0cca3e3685] to [71131960ae].
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 | # import "OFFileManager.h" # import "OFFileURLHandler.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" static OFCharacterSet *URLAllowedCharacterSet = nil; static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; | > > > > > > > > > > > > > > > > > | | < > | > | > | > > | | | > | > > | | | > | > > | | | < > | < | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | # import "OFFileManager.h" # import "OFFileURLHandler.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "once.h" @interface OFURLAllowedCharacterSetBase: OFCharacterSet @end @interface OFURLAllowedCharacterSet: OFURLAllowedCharacterSetBase @end @interface OFURLSchemeAllowedCharacterSet: OFURLAllowedCharacterSetBase @end @interface OFURLPathAllowedCharacterSet: OFURLAllowedCharacterSetBase @end @interface OFURLQueryOrFragmentAllowedCharacterSet: OFURLAllowedCharacterSetBase @end static OFCharacterSet *URLAllowedCharacterSet = nil; static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; static of_once_t URLAllowedCharacterSetOnce = OF_ONCE_INIT; static of_once_t URLQueryOrFragmentAllowedCharacterSetOnce = OF_ONCE_INIT; static void initURLAllowedCharacterSet(void) { URLAllowedCharacterSet = [[OFURLAllowedCharacterSet alloc] init]; } static void initURLSchemeAllowedCharacterSet(void) { URLSchemeAllowedCharacterSet = [[OFURLSchemeAllowedCharacterSet alloc] init]; } static void initURLPathAllowedCharacterSet(void) { URLPathAllowedCharacterSet = [[OFURLPathAllowedCharacterSet alloc] init]; } static void initURLQueryOrFragmentAllowedCharacterSet(void) { URLQueryOrFragmentAllowedCharacterSet = [[OFURLQueryOrFragmentAllowedCharacterSet alloc] init]; } @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet; @end bool of_url_is_ipv6_host(OFString *host) { const char *UTF8String = host.UTF8String; bool hasColon = false; |
︙ | ︙ | |||
88 89 90 91 92 93 94 | UTF8String++; } return hasColon; } @implementation OFURLAllowedCharacterSetBase | < < < < < < < < < < | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | UTF8String++; } return hasColon; } @implementation OFURLAllowedCharacterSetBase - (instancetype)autorelease { return self; } - (instancetype)retain { |
︙ | ︙ | |||
119 120 121 122 123 124 125 | - (unsigned int)retainCount { return OF_RETAIN_COUNT_MAX; } @end @implementation OFURLAllowedCharacterSet | < < < < < < < < < < < < < | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | - (unsigned int)retainCount { return OF_RETAIN_COUNT_MAX; } @end @implementation OFURLAllowedCharacterSet - (bool)characterIsMember: (of_unichar_t)character { if (character < CHAR_MAX && of_ascii_isalnum(character)) return true; switch (character) { case '-': |
︙ | ︙ | |||
161 162 163 164 165 166 167 | default: return false; } } @end @implementation OFURLSchemeAllowedCharacterSet | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | default: return false; } } @end @implementation OFURLSchemeAllowedCharacterSet - (bool)characterIsMember: (of_unichar_t)character { if (character < CHAR_MAX && of_ascii_isalnum(character)) return true; switch (character) { case '+': case '-': case '.': return true; default: return false; } } @end @implementation OFURLPathAllowedCharacterSet - (bool)characterIsMember: (of_unichar_t)character { if (character < CHAR_MAX && of_ascii_isalnum(character)) return true; switch (character) { case '-': |
︙ | ︙ | |||
238 239 240 241 242 243 244 | default: return false; } } @end @implementation OFURLQueryOrFragmentAllowedCharacterSet | < < < < < < < < < < < < < < | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | default: return false; } } @end @implementation OFURLQueryOrFragmentAllowedCharacterSet - (bool)characterIsMember: (of_unichar_t)character { if (character < CHAR_MAX && of_ascii_isalnum(character)) return true; switch (character) { case '-': |
︙ | ︙ | |||
285 286 287 288 289 290 291 | default: return false; } } @end @implementation OFInvertedCharacterSetWithoutPercent | < < < < < | > | | | > > > > > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | default: return false; } } @end @implementation OFInvertedCharacterSetWithoutPercent - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @try { _characterSet = [characterSet retain]; _characterIsMember = (bool (*)(id, SEL, of_unichar_t)) [_characterSet methodForSelector: @selector(characterIsMember:)]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_characterSet release]; |
︙ | ︙ | |||
321 322 323 324 325 326 327 | void of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc] | | > > > | > > | > > | > > | > > > | > | > | > | > | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | void of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc] initWithCharacterSet: characterSet] autorelease]; if ([string indexOfCharacterFromSet: characterSet] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); } @implementation OFCharacterSet (URLCharacterSets) + (OFCharacterSet *)URLSchemeAllowedCharacterSet { static of_once_t onceControl = OF_ONCE_INIT; of_once(&onceControl, initURLSchemeAllowedCharacterSet); return URLSchemeAllowedCharacterSet; } + (OFCharacterSet *)URLHostAllowedCharacterSet { of_once(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLUserAllowedCharacterSet { of_once(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLPasswordAllowedCharacterSet { of_once(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLPathAllowedCharacterSet { static of_once_t onceControl = OF_ONCE_INIT; of_once(&onceControl, initURLPathAllowedCharacterSet); return URLPathAllowedCharacterSet; } + (OFCharacterSet *)URLQueryAllowedCharacterSet { of_once(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } + (OFCharacterSet *)URLFragmentAllowedCharacterSet { of_once(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } @end @implementation OFURL + (instancetype)URL { return [[[self alloc] init] autorelease]; |
︙ | ︙ |
Modified src/OFWin32ConsoleStdIOStream.h from [e3e1fc8637] to [77f92f2723].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #import "OFStdIOStream.h" OF_ASSUME_NONNULL_BEGIN @interface OFWin32ConsoleStdIOStream: OFStdIOStream { HANDLE _handle; of_char16_t _incompleteUTF16Surrogate; char _incompleteUTF8Surrogate[4]; size_t _incompleteUTF8SurrogateLen; } @end OF_ASSUME_NONNULL_END | > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #import "OFStdIOStream.h" OF_ASSUME_NONNULL_BEGIN @interface OFWin32ConsoleStdIOStream: OFStdIOStream { HANDLE _handle; WORD _attributes; of_char16_t _incompleteUTF16Surrogate; char _incompleteUTF8Surrogate[4]; size_t _incompleteUTF8SurrogateLen; } @end OF_ASSUME_NONNULL_END |
Modified src/OFWin32ConsoleStdIOStream.m from [f6d82fa9cc] to [959c780c29].
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include "config.h" #include <assert.h> #include <errno.h> #include <io.h> #import "OFWin32ConsoleStdIOStream.h" #import "OFData.h" #import "OFStdIOStream+Private.h" #import "OFString.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> @implementation OFWin32ConsoleStdIOStream + (void)load { int fd; if (self != [OFWin32ConsoleStdIOStream class]) | > > > > > > > > > > > > > > > > > > > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #include "config.h" #include <assert.h> #include <errno.h> #include <io.h> #import "OFWin32ConsoleStdIOStream.h" #import "OFColor.h" #import "OFData.h" #import "OFStdIOStream+Private.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> static of_string_encoding_t codepageToEncoding(UINT codepage) { switch (codepage) { case 437: return OF_STRING_ENCODING_CODEPAGE_437; case 850: return OF_STRING_ENCODING_CODEPAGE_850; case 858: return OF_STRING_ENCODING_CODEPAGE_858; case 1251: return OF_STRING_ENCODING_WINDOWS_1251; case 1252: return OF_STRING_ENCODING_WINDOWS_1252; default: @throw [OFInvalidEncodingException exception]; } } @implementation OFWin32ConsoleStdIOStream + (void)load { int fd; if (self != [OFWin32ConsoleStdIOStream class]) |
︙ | ︙ | |||
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | - (instancetype)of_initWithFileDescriptor: (int)fd { self = [super of_initWithFileDescriptor: fd]; @try { DWORD mode; _handle = (HANDLE)_get_osfhandle(fd); if (_handle == INVALID_HANDLE_VALUE) @throw [OFInvalidArgumentException exception]; /* Not a console: Treat it as a regular OFStdIOStream */ if (!GetConsoleMode(_handle, &mode)) object_setClass(self, [OFStdIOStream class]); } @catch (id e) { [self release]; @throw e; } return self; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { void *pool = objc_autoreleasePoolPush(); char *buffer = buffer_; of_char16_t *UTF16; size_t j = 0; | > > > > | > | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | - (instancetype)of_initWithFileDescriptor: (int)fd { self = [super of_initWithFileDescriptor: fd]; @try { DWORD mode; CONSOLE_SCREEN_BUFFER_INFO csbi; _handle = (HANDLE)_get_osfhandle(fd); if (_handle == INVALID_HANDLE_VALUE) @throw [OFInvalidArgumentException exception]; /* Not a console: Treat it as a regular OFStdIOStream */ if (!GetConsoleMode(_handle, &mode)) object_setClass(self, [OFStdIOStream class]); if (GetConsoleScreenBufferInfo(_handle, &csbi)) _attributes = csbi.wAttributes; } @catch (id e) { [self release]; @throw e; } return self; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { void *pool = objc_autoreleasePoolPush(); char *buffer = buffer_; of_char16_t *UTF16; size_t j = 0; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; UTF16 = [self allocMemoryWithSize: sizeof(of_char16_t) count: length]; @try { DWORD UTF16Len; OFMutableData *rest = nil; size_t i = 0; if ([OFSystemInfo isWindowsNT]) { if (!ReadConsoleW(_handle, UTF16, (DWORD)length, &UTF16Len, NULL)) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length * 2 errNo: EIO]; } else { of_string_encoding_t encoding; OFString *string; size_t stringLen; if (!ReadConsoleA(_handle, (char *)UTF16, (DWORD)length, &UTF16Len, NULL)) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: EIO]; encoding = codepageToEncoding(GetConsoleCP()); string = [OFString stringWithCString: (char *)UTF16 encoding: encoding length: UTF16Len]; stringLen = string.UTF16StringLength; if (stringLen > length) @throw [OFOutOfRangeException exception]; UTF16Len = (DWORD)stringLen; memcpy(UTF16, string.UTF16String, stringLen); } if (UTF16Len > 0 && _incompleteUTF16Surrogate != 0) { of_unichar_t c = (((_incompleteUTF16Surrogate & 0x3FF) << 10) | (UTF16[0] & 0x3FF)) + 0x10000; char UTF8[4]; size_t UTF8Len; |
︙ | ︙ | |||
267 268 269 270 271 272 273 | UTF16Len = 2; } else { UTF16[0] = c; UTF16Len = 1; } } | > | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | UTF16Len = 2; } else { UTF16[0] = c; UTF16Len = 1; } } if ([OFSystemInfo isWindowsNT]) { if (!WriteConsoleW(_handle, UTF16, UTF16Len, &bytesWritten, NULL)) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: UTF16Len * 2 bytesWritten: bytesWritten * 2 errNo: EIO]; } else { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithUTF16String: UTF16 length: UTF16Len]; of_string_encoding_t encoding = codepageToEncoding(GetConsoleOutputCP()); size_t nativeLen = [string cStringLengthWithEncoding: encoding]; if (nativeLen > UINT32_MAX) @throw [OFOutOfRangeException exception]; if (!WriteConsoleA(_handle, [string cStringWithEncoding: encoding], (DWORD)nativeLen, &bytesWritten, NULL)) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: nativeLen bytesWritten: bytesWritten errNo: EIO]; objc_autoreleasePoolPop(pool); } if (bytesWritten != UTF16Len) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: UTF16Len * 2 bytesWritten: bytesWritten * 2 errNo: 0]; |
︙ | ︙ | |||
327 328 329 330 331 332 333 | i += UTF8Len; } if (j > UINT32_MAX) @throw [OFOutOfRangeException exception]; | > | > | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 | i += UTF8Len; } if (j > UINT32_MAX) @throw [OFOutOfRangeException exception]; if ([OFSystemInfo isWindowsNT]) { if (!WriteConsoleW(_handle, tmp, (DWORD)j, &bytesWritten, NULL)) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: EIO]; } else { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithUTF16String: tmp length: j]; of_string_encoding_t encoding = codepageToEncoding(GetConsoleOutputCP()); size_t nativeLen = [string cStringLengthWithEncoding: encoding]; if (nativeLen > UINT32_MAX) @throw [OFOutOfRangeException exception]; if (!WriteConsoleA(_handle, [string cStringWithEncoding: encoding], (DWORD)nativeLen, &bytesWritten, NULL)) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: nativeLen bytesWritten: bytesWritten errNo: EIO]; objc_autoreleasePoolPop(pool); } if (bytesWritten != j) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: 0]; } @finally { [self freeMemory: tmp]; } /* * We do not count in bytes when writing to the Win32 console. But * since any incomplete write is an exception here anyway, we can just * return length. */ return length; } - (bool)hasTerminal { /* * We can never get here if there is no terminal, as the initializer * changes the class to OFStdIOStream in that case. */ return true; } - (int)columns { CONSOLE_SCREEN_BUFFER_INFO csbi; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return -1; return csbi.dwSize.X; } - (int)rows { /* * The buffer size returned is almost always larger than the window * size, so this is useless. */ return -1; } - (void)setForegroundColor: (OFColor *)color { CONSOLE_SCREEN_BUFFER_INFO csbi; float red, green, blue; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); [color getRed: &red green: &green blue: &blue alpha: NULL]; if (red >= 0.25) csbi.wAttributes |= FOREGROUND_RED; if (green >= 0.25) csbi.wAttributes |= FOREGROUND_GREEN; if (blue >= 0.25) csbi.wAttributes |= FOREGROUND_BLUE; if (red >= 0.75 || green >= 0.75 || blue >= 0.75) csbi.wAttributes |= FOREGROUND_INTENSITY; SetConsoleTextAttribute(_handle, csbi.wAttributes); } - (void)setBackgroundColor: (OFColor *)color { CONSOLE_SCREEN_BUFFER_INFO csbi; float red, green, blue; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY); [color getRed: &red green: &green blue: &blue alpha: NULL]; if (red >= 0.25) csbi.wAttributes |= BACKGROUND_RED; if (green >= 0.25) csbi.wAttributes |= BACKGROUND_GREEN; if (blue >= 0.25) csbi.wAttributes |= BACKGROUND_BLUE; if (red >= 0.75 || green >= 0.75 || blue >= 0.75) csbi.wAttributes |= BACKGROUND_INTENSITY; SetConsoleTextAttribute(_handle, csbi.wAttributes); } - (void)reset { SetConsoleTextAttribute(_handle, _attributes); } - (void)clear { static COORD zero = { 0, 0 }; CONSOLE_SCREEN_BUFFER_INFO csbi; DWORD bytesWritten; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; if (!FillConsoleOutputCharacter(_handle, ' ', csbi.dwSize.X * csbi.dwSize.Y, zero, &bytesWritten)) return; if (!FillConsoleOutputAttribute(_handle, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, zero, &bytesWritten)) return; SetConsoleCursorPosition(_handle, zero); } - (void)eraseLine { CONSOLE_SCREEN_BUFFER_INFO csbi; DWORD bytesWritten; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.dwCursorPosition.X = 0; if (!FillConsoleOutputCharacter(_handle, ' ', csbi.dwSize.X, csbi.dwCursorPosition, &bytesWritten)) return; FillConsoleOutputAttribute(_handle, csbi.wAttributes, csbi.dwSize.X, csbi.dwCursorPosition, &bytesWritten); } - (void)setCursorColumn: (unsigned int)column { CONSOLE_SCREEN_BUFFER_INFO csbi; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.dwCursorPosition.X = column; SetConsoleCursorPosition(_handle, csbi.dwCursorPosition); } - (void)setCursorPosition: (of_point_t)position { if (position.x < 0 || position.y < 0) @throw [OFInvalidArgumentException exception]; SetConsoleCursorPosition(_handle, (COORD){ position.x, position.y }); } - (void)setRelativeCursorPosition: (of_point_t)position { CONSOLE_SCREEN_BUFFER_INFO csbi; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.dwCursorPosition.X += position.x; csbi.dwCursorPosition.Y += position.y; SetConsoleCursorPosition(_handle, csbi.dwCursorPosition); } @end |
Modified src/OFWindowsRegistryKey.h from [e667684d2c] to [1bed1bb2f4].
︙ | ︙ | |||
128 129 130 131 132 133 134 | * `lpdwDisposition`. * @return The subkey with the specified path */ - (OFWindowsRegistryKey *) createSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights | | | < < < < | < | < < < < < | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | * `lpdwDisposition`. * @return The subkey with the specified path */ - (OFWindowsRegistryKey *) createSubkeyAtPath: (OFString *)path 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 */ - (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 */ |
︙ | ︙ |
Modified src/OFWindowsRegistryKey.m from [c6d5abaa71] to [adb04f0d00].
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | * file. */ #include "config.h" #import "OFWindowsRegistryKey.h" #import "OFData.h" #include <windows.h> #import "OFCreateWindowsRegistryKeyFailedException.h" #import "OFDeleteWindowsRegistryKeyFailedException.h" #import "OFDeleteWindowsRegistryValueFailedException.h" #import "OFGetWindowsRegistryValueFailedException.h" #import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" #import "OFOutOfRangeException.h" #import "OFSetWindowsRegistryValueFailedException.h" @interface OFWindowsRegistryKey () - (instancetype)of_initWithHKey: (HKEY)hKey | > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | * file. */ #include "config.h" #import "OFWindowsRegistryKey.h" #import "OFData.h" #import "OFLocale.h" #import "OFSystemInfo.h" #include <windows.h> #import "OFCreateWindowsRegistryKeyFailedException.h" #import "OFDeleteWindowsRegistryKeyFailedException.h" #import "OFDeleteWindowsRegistryValueFailedException.h" #import "OFGetWindowsRegistryValueFailedException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" #import "OFOutOfRangeException.h" #import "OFSetWindowsRegistryValueFailedException.h" @interface OFWindowsRegistryKey () - (instancetype)of_initWithHKey: (HKEY)hKey |
︙ | ︙ | |||
103 104 105 106 107 108 109 | options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; | > | | > > > > > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; if ([OFSystemInfo isWindowsNT]) status = RegOpenKeyExW(_hKey, path.UTF16String, options, securityAndAccessRights, &subKey); else status = RegOpenKeyExA(_hKey, [path cStringWithEncoding: [OFLocale encoding]], options, securityAndAccessRights, &subKey); if (status != ERROR_SUCCESS) { if (status == ERROR_FILE_NOT_FOUND) { objc_autoreleasePoolPop(pool); return nil; } @throw [OFOpenWindowsRegistryKeyFailedException exceptionWithRegistryKey: self |
︙ | ︙ | |||
140 141 142 143 144 145 146 | } - (OFWindowsRegistryKey *) createSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (LPSECURITY_ATTRIBUTES)securityAttributes | | > | | | > > > > > > > < | < | > > > > > | > | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | } - (OFWindowsRegistryKey *) createSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (LPSECURITY_ATTRIBUTES)securityAttributes disposition: (DWORD *)disposition { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; if ([OFSystemInfo isWindowsNT]) status = RegCreateKeyExW(_hKey, path.UTF16String, 0, NULL, options, securityAndAccessRights, securityAttributes, &subKey, NULL); else status = RegCreateKeyExA(_hKey, [path cStringWithEncoding: [OFLocale encoding]], 0, NULL, options, securityAndAccessRights, securityAttributes, &subKey, NULL); if (status != ERROR_SUCCESS) @throw [OFCreateWindowsRegistryKeyFailedException exceptionWithRegistryKey: self path: path options: options securityAndAccessRights: securityAndAccessRights securityAttributes: securityAttributes status: status]; objc_autoreleasePoolPop(pool); return [[[OFWindowsRegistryKey alloc] of_initWithHKey: subKey close: true] autorelease]; } - (OFData *)dataForValue: (OFString *)value type: (DWORD *)type { void *pool = objc_autoreleasePoolPush(); BYTE stackBuffer[256], *buffer = stackBuffer; DWORD length = sizeof(stackBuffer); OFMutableData *ret = nil; bool winNT = [OFSystemInfo isWindowsNT]; LSTATUS status; for (;;) { if (winNT) status = RegQueryValueExW(_hKey, value.UTF16String, NULL, type, buffer, &length); else status = RegQueryValueExA(_hKey, [value cStringWithEncoding: [OFLocale encoding]], NULL, type, buffer, &length); switch (status) { case ERROR_SUCCESS: if (buffer == stackBuffer) { objc_autoreleasePoolPop(pool); return [OFData dataWithItems: buffer |
︙ | ︙ | |||
211 212 213 214 215 216 217 | buffer = ret.mutableItems; continue; default: @throw [OFGetWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value | < < > | | > > > > > > < < < < | < > < < | < < > > > > > > > | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | buffer = ret.mutableItems; continue; default: @throw [OFGetWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value status: status]; } } } - (void)setData: (OFData *)data forValue: (OFString *)value type: (DWORD)type { size_t length = data.count * data.itemSize; LSTATUS status; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; if ([OFSystemInfo isWindowsNT]) status = RegSetValueExW(_hKey, value.UTF16String, 0, type, data.items, (DWORD)length); else status = RegSetValueExA(_hKey, [value cStringWithEncoding: [OFLocale encoding]], 0, type, data.items, (DWORD)length); if (status != ERROR_SUCCESS) @throw [OFSetWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value data: data type: type status: status]; } - (OFString *)stringForValue: (OFString *)value { return [self stringForValue: value type: NULL]; } - (OFString *)stringForValue: (OFString *)value type: (DWORD *)typeOut { void *pool = objc_autoreleasePoolPush(); DWORD type; OFData *data = [self dataForValue: value type: &type]; OFString *ret; if (data == nil) return nil; if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_LINK) @throw [OFInvalidEncodingException exception]; if (data.itemSize != 1) @throw [OFInvalidFormatException exception]; if ([OFSystemInfo isWindowsNT]) { const of_char16_t *UTF16String = data.items; size_t length = data.count; if (length % 2 == 1) @throw [OFInvalidFormatException exception]; length /= 2; /* * REG_SZ and REG_EXPAND_SZ contain a \0, but can contain data * after it that should be ignored. */ for (size_t i = 0; i < length; i++) { if (UTF16String[i] == 0) { length = i; break; } } ret = [[OFString alloc] initWithUTF16String: UTF16String length: length]; } else { const char *cString = data.items; size_t length = data.count; /* * REG_SZ and REG_EXPAND_SZ contain a \0, but can contain data * after it that should be ignored. */ for (size_t i = 0; i < length; i++) { if (cString[i] == 0) { length = i; break; } } ret = [[OFString alloc] initWithCString: cString encoding: [OFLocale encoding] length: length]; } if (typeOut != NULL) *typeOut = type; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (void)setString: (OFString *)string |
︙ | ︙ | |||
306 307 308 309 310 311 312 | - (void)setString: (OFString *)string forValue: (OFString *)value type: (DWORD)type { void *pool = objc_autoreleasePoolPush(); OFData *data; | > | | | > > > > > > > > > > | > > > > | > | > > > > | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | - (void)setString: (OFString *)string forValue: (OFString *)value type: (DWORD)type { void *pool = objc_autoreleasePoolPush(); OFData *data; if ([OFSystemInfo isWindowsNT]) data = [OFData dataWithItems: string.UTF16String itemSize: sizeof(of_char16_t) count: string.UTF16StringLength + 1]; else { of_string_encoding_t encoding = [OFLocale encoding]; const char *cString = [string cStringWithEncoding: encoding]; size_t length = [string cStringLengthWithEncoding: encoding]; data = [OFData dataWithItems: cString count: length + 1]; } [self setData: data forValue: value type: type]; objc_autoreleasePoolPop(pool); } - (void)deleteValue: (OFString *)value { void *pool = objc_autoreleasePoolPush(); LSTATUS status; if ([OFSystemInfo isWindowsNT]) status = RegDeleteValueW(_hKey, value.UTF16String); else status = RegDeleteValueA(_hKey, [value cStringWithEncoding: [OFLocale encoding]]); if (status != ERROR_SUCCESS) @throw [OFDeleteWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value status: status]; objc_autoreleasePoolPop(pool); } - (void)deleteSubkeyAtPath: (OFString *)subkeyPath { void *pool = objc_autoreleasePoolPush(); LSTATUS status; if ([OFSystemInfo isWindowsNT]) status = RegDeleteKeyW(_hKey, subkeyPath.UTF16String); else status = RegDeleteKeyA(_hKey, [subkeyPath cStringWithEncoding: [OFLocale encoding]]); if (status != ERROR_SUCCESS) @throw [OFDeleteWindowsRegistryKeyFailedException exceptionWithRegistryKey: self subkeyPath: subkeyPath status: status]; objc_autoreleasePoolPop(pool); } @end |
Modified src/OFXMLParser.m from [d4fd816fdb] to [7ad1f08170].
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFInvalidFormatException.h" #import "OFMalformedXMLException.h" #import "OFOutOfRangeException.h" #import "OFUnboundPrefixException.h" typedef void (*state_function_t)(id, SEL); static SEL selectors[OF_XMLPARSER_NUM_STATES]; | > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #import "OFStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFMalformedXMLException.h" #import "OFOutOfRangeException.h" #import "OFUnboundPrefixException.h" typedef void (*state_function_t)(id, SEL); static SEL selectors[OF_XMLPARSER_NUM_STATES]; |
︙ | ︙ | |||
476 477 478 479 480 481 482 | if ([attribute isEqual: @"version"]) { if (![value hasPrefix: @"1."]) return false; hasVersion = true; } | | > > | > > > > > | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | if ([attribute isEqual: @"version"]) { if (![value hasPrefix: @"1."]) return false; hasVersion = true; } if ([attribute isEqual: @"encoding"]) { @try { _encoding = of_string_parse_encoding(value); } @catch (OFInvalidArgumentException *e) { @throw [OFInvalidEncodingException exception]; } } last = i + 1; PIState = 0; break; } } |
︙ | ︙ |
Modified src/ObjFW.h from [e5a1a42cc2] to [58db83c230].
︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 | # import "OFUDPSocket.h" # import "OFTLSSocket.h" # import "OFKernelEventObserver.h" # import "OFDNSQuery.h" # import "OFDNSResourceRecord.h" # import "OFDNSResponse.h" # import "OFDNSResolver.h" #endif #ifdef OF_HAVE_SOCKETS # ifdef OF_HAVE_THREADS # import "OFHTTPClient.h" # endif # import "OFHTTPCookie.h" # import "OFHTTPCookieManager.h" | > > > > > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | # import "OFUDPSocket.h" # import "OFTLSSocket.h" # import "OFKernelEventObserver.h" # import "OFDNSQuery.h" # import "OFDNSResourceRecord.h" # import "OFDNSResponse.h" # import "OFDNSResolver.h" # ifdef OF_HAVE_IPX # import "OFIPXSocket.h" # import "OFSPXSocket.h" # import "OFSPXStreamSocket.h" # endif # ifdef OF_HAVE_SCTP # import "OFSCTPSocket.h" # endif #endif #ifdef OF_HAVE_SOCKETS # ifdef OF_HAVE_THREADS # import "OFHTTPClient.h" # endif # import "OFHTTPCookie.h" # import "OFHTTPCookieManager.h" |
︙ | ︙ |
Modified src/block.h from [bf1e73c83e] to [6724cf2142].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * 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. */ | > > > | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * * 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. */ #ifndef OBJFW_BLOCK_H #define OBJFW_BLOCK_H #include "macros.h" OF_ASSUME_NONNULL_BEGIN typedef struct of_block_literal_t { #ifdef __OBJC__ Class isa; #else |
︙ | ︙ | |||
66 67 68 69 70 71 72 | ((__typeof__(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) #endif #ifndef Block_release # define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) #endif OF_ASSUME_NONNULL_END | > > | 69 70 71 72 73 74 75 76 77 | ((__typeof__(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) #endif #ifndef Block_release # define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) #endif OF_ASSUME_NONNULL_END #endif |
Modified src/exceptions/OFBindFailedException.h from [de856810d3] to [5b18a08191].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif OF_ASSUME_NONNULL_BEGIN /*! * @class OFBindFailedException \ * OFBindFailedException.h ObjFW/OFBindFailedException.h * * @brief An exception indicating that binding a socket failed. */ @interface OFBindFailedException: OFException { id _socket; OFString *_host; uint16_t _port; 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 socket which could not be bound. */ @property (readonly, nonatomic) id socket; /*! * @brief The errno of the error that occurred. | > > > > > > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! * @class OFBindFailedException \ * OFBindFailedException.h ObjFW/OFBindFailedException.h * * @brief An exception indicating that binding a socket failed. */ @interface OFBindFailedException: OFException { id _socket; /* IP */ OFString *_host; uint16_t _port; /* 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. |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | * @return A new, autoreleased bind failed exception */ + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port 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 * @param errNo The errno of the error that occurred * @return An initialized bind failed exception */ - (instancetype)initWithHost: (OFString *)host port: (uint16_t)port socket: (id)socket | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | * @return A new, autoreleased bind failed exception */ + (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 * @param errNo The errno of the error that occurred * @return A new, autoreleased bind failed exception */ + (instancetype)exceptionWithPort: (uint16_t)port packetType: (uint8_t)packetType 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 * @param errNo The errno of the error that occurred * @return An initialized bind failed exception */ - (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 * @param errNo The errno of the error that occurred * @return An initialized bind failed exception */ - (instancetype)initWithPort: (uint16_t)port packetType: (uint8_t)packetType socket: (id)socket errNo: (int)errNo; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFBindFailedException.m from [a4be0b4e2f] to [66d49adee0].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #include "config.h" #import "OFBindFailedException.h" #import "OFString.h" @implementation OFBindFailedException | | > | | > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > | | | | > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | #include "config.h" #import "OFBindFailedException.h" #import "OFString.h" @implementation OFBindFailedException @synthesize host = _host, port = _port, packetType = _packetType; @synthesize socket = _socket, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithHost: host port: port socket: sock errNo: errNo] autorelease]; } + (instancetype)exceptionWithPort: (uint16_t)port packetType: (uint8_t)packetType socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithPort: port packetType: packetType socket: sock errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithHost: (OFString *)host port: (uint16_t)port socket: (id)sock errNo: (int)errNo { self = [super init]; @try { _host = [host copy]; _port = port; _socket = [sock retain]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithPort: (uint16_t)port packetType: (uint8_t)packetType socket: (id)sock errNo: (int)errNo { self = [super init]; @try { _port = port; _packetType = packetType; _socket = [sock retain]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_socket release]; [super dealloc]; } - (OFString *)description { if (_host != nil) return [OFString stringWithFormat: @"Binding to port %" @PRIu16 @" on host %@ failed in " @"socket of type %@: %@", _port, _host, [_socket class], of_strerror(_errNo)]; else return [OFString stringWithFormat: @"Binding to port %" @PRIx16 @" for packet type %" @PRIx8 @" failed in socket of type %@: %@", _port, _packetType, [_socket class], of_strerror(_errNo)]; } @end |
Modified src/exceptions/OFConnectionFailedException.h from [e2e47e53e8] to [cd5a362f90].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif OF_ASSUME_NONNULL_BEGIN /*! * @class OFConnectionFailedException \ * OFConnectionFailedException.h ObjFW/OFConnectionFailedException.h * * @brief An exception indicating that a connection could not be established. */ @interface OFConnectionFailedException: OFException { id _socket; OFString *_host; uint16_t _port; 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 errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; | > > > > > > > > > > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #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. */ @interface OFConnectionFailedException: OFException { id _socket; OFString *_host; uint16_t _port; 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; |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | * @return A new, autoreleased connection failed exception */ + (instancetype)exceptionWithHost: (nullable OFString *)host port: (uint16_t)port 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 * @param errNo The errno of the error that occurred * @return An initialized connection failed exception */ - (instancetype)initWithHost: (nullable OFString *)host port: (uint16_t)port socket: (id)socket | > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | * @return A new, autoreleased connection failed exception */ + (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 * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return A new, autoreleased connection failed exception */ + (instancetype)exceptionWithNode: (unsigned char [_Nullable IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port 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 * @param errNo The errno of the error that occurred * @return An initialized connection failed exception */ - (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 * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return An initialized connection failed exception */ - (instancetype)initWithNode: (unsigned char [_Nullable IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port socket: (id)socket errNo: (int)errNo; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFConnectionFailedException.m from [19c84f566e] to [7c382ce8cb].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #include "config.h" #import "OFConnectionFailedException.h" #import "OFString.h" @implementation OFConnectionFailedException | | > | | > > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #include "config.h" #import "OFConnectionFailedException.h" #import "OFString.h" @implementation OFConnectionFailedException @synthesize host = _host, port = _port, network = _network, socket = _socket; @synthesize errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithHost: host port: port socket: sock errNo: errNo] autorelease]; } + (instancetype)exceptionWithNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithNode: node network: network port: port socket: sock errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithHost: (OFString *)host port: (uint16_t)port socket: (id)sock errNo: (int)errNo { self = [super init]; @try { _host = [host copy]; _port = port; _socket = [sock retain]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port socket: (id)sock errNo: (int)errNo { self = [super init]; @try { memcpy(_node, node, IPX_NODE_LEN); _network = network; _port = port; _socket = [sock retain]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_socket release]; [super dealloc]; } - (unsigned char *)node { return _node; } - (OFString *)description { if (_host != nil) return [OFString stringWithFormat: @"A connection to %@ on port %" @PRIu16 @" could not be " @"established in socket of type %@: %@", _host, _port, [_socket class], of_strerror(_errNo)]; else if (memcmp(_node, "\0\0\0\0\0", IPX_NODE_LEN) == 0) return [OFString stringWithFormat: @"A connection to %02X%02X%02X%02X%02X%02X port %" @PRIu16 @" on network %" @PRIX32 " could not be established in " @"socket of type %@: %@", _node[0], _node[1], _node[2], _node[3], _node[4], _node[5], _port, _network, [_socket class], of_strerror(_errNo)]; else return [OFString stringWithFormat: @"A connection could not be established in socket of " @"type %@: %@", [_socket class], of_strerror(_errNo)]; } @end |
Modified src/exceptions/OFException.m from [0f0c49d47c] to [bf7ff24437].
︙ | ︙ | |||
23 24 25 26 27 28 29 | #include <string.h> #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" | | | | > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <string.h> #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" #import "OFArray.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLockFailedException.h" #import "OFUnlockFailedException.h" #if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS) # import "mutex.h" |
︙ | ︙ | |||
86 87 88 89 90 91 92 | #ifdef HAVE_STRERROR_R char buffer[256]; #endif if (errNo == 0) return @"Unknown error"; | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #ifdef HAVE_STRERROR_R char buffer[256]; #endif if (errNo == 0) return @"Unknown error"; #if defined(OF_WINDOWS) && defined(OF_HAVE_SOCKETS) /* * These were translated from WSAE* errors to errno and thus Win32's * strerror_r() does not know about them. * * FIXME: These could have better descriptions! */ switch (errNo) { |
︙ | ︙ | |||
167 168 169 170 171 172 173 | case EUSERS: return @"EUSERS"; case EWOULDBLOCK: return @"EWOULDBLOCK"; } #endif | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | case EUSERS: return @"EUSERS"; case EWOULDBLOCK: return @"EWOULDBLOCK"; } #endif #if defined(STRERROR_R_RETURNS_CHARP) /* glibc uses a different strerror_r when _GNU_SOURCE is defined */ char *string; if ((string = strerror_r(errNo, buffer, 256)) == NULL) return @"Unknown error (strerror_r failed)"; ret = [OFString stringWithCString: string |
︙ | ︙ | |||
207 208 209 210 211 212 213 214 | return ret; } #ifdef OF_WINDOWS OFString * of_windows_status_to_string(LSTATUS status) { void *buffer; | > < > | | > | | | | > | | | > | > > > > > > > > > > > > > > > > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | return ret; } #ifdef OF_WINDOWS OFString * of_windows_status_to_string(LSTATUS status) { OFString *string = nil; void *buffer; if ([OFSystemInfo isWindowsNT]) { if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, status, 0, (LPWSTR)&buffer, 0, NULL) != 0) { @try { string = [OFString stringWithUTF16String: buffer]; } @finally { LocalFree(buffer); } } } else { if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, status, 0, (LPSTR)&buffer, 0, NULL) != 0) { @try { string = [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; } @finally { LocalFree(buffer); } } } if (string == nil) string = [OFString stringWithFormat: @"Status code %u", status]; return string; } #endif #ifdef HAVE__UNWIND_BACKTRACE |
︙ | ︙ |
Modified src/exceptions/OFGetOptionFailedException.h from [4a4969db85] to [70541d2ad1].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN | < < | | | | | | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | * file. */ #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. */ @interface OFGetOptionFailedException: OFException { 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 */ + (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 */ - (instancetype)initWithObject: (id)object errNo: (int)errNo OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFGetOptionFailedException.m from [2c7cb59f5d] to [a2104983ac].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #include "config.h" #import "OFGetOptionFailedException.h" #import "OFString.h" | < | | | | | | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | * file. */ #include "config.h" #import "OFGetOptionFailedException.h" #import "OFString.h" @implementation OFGetOptionFailedException @synthesize object = _object, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo { return [[[self alloc] initWithObject: object errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithObject: (id)object errNo: (int)errNo { self = [super init]; _object = [object retain]; _errNo = errNo; return self; } - (void)dealloc { [_object release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Getting an option in an object of type %@ failed: %@", [_object class], of_strerror(_errNo)]; } @end |
Modified src/exceptions/OFGetWindowsRegistryValueFailedException.h from [d8a164b776] to [f3d99ecbde].
︙ | ︙ | |||
28 29 30 31 32 33 34 | * ObjFW/OFGetWindowsRegistryValueFailedException.h * * @brief An exception indicating that getting a Windows registry value failed. */ @interface OFGetWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; | | < < < < < < < < < < < < < < < < < < | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | * ObjFW/OFGetWindowsRegistryValueFailedException.h * * @brief An exception indicating that getting a Windows registry value failed. */ @interface OFGetWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; 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 * @param value The value which could not be retrieved * @param status The status returned by RegGetValueEx() * @return A new, autoreleased get Windows registry value failed exception */ + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey 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 * @param value The value which could not be retrieved * @param status The status returned by RegGetValueEx() * @return An initialized get Windows registry value failed exception */ - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (nullable OFString *)value status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFGetWindowsRegistryValueFailedException.m from [3f3297c06e] to [1c37f45def].
︙ | ︙ | |||
16 17 18 19 20 21 22 | */ #include "config.h" #import "OFGetWindowsRegistryValueFailedException.h" @implementation OFGetWindowsRegistryValueFailedException | | < < < < < < < < < < | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | */ #include "config.h" #import "OFGetWindowsRegistryValueFailedException.h" @implementation OFGetWindowsRegistryValueFailedException @synthesize registryKey = _registryKey, value = _value, status = _status; + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (OFString *)value status: (LSTATUS)status { return [[[self alloc] initWithRegistryKey: registryKey value: value status: status] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (OFString *)value status: (LSTATUS)status { self = [super init]; @try { _registryKey = [registryKey retain]; _value = [value copy]; _status = status; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_registryKey release]; [_value release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to get value %@: %@", _value, of_windows_status_to_string(_status)]; } @end |
Modified src/macros.h from [9bed6604d9] to [b900515d8a].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * 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 "objfw-defs.h" #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | * 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. */ #ifndef OBJFW_MACROS_H #define OBJFW_MACROS_H #include "objfw-defs.h" #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS |
︙ | ︙ | |||
33 34 35 36 37 38 39 | #include <sys/time.h> #include "platform.h" #ifdef OF_OBJFW_RUNTIME # ifdef OF_COMPILING_OBJFW | | | | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include <sys/time.h> #include "platform.h" #ifdef OF_OBJFW_RUNTIME # ifdef OF_COMPILING_OBJFW # include "ObjFWRT.h" # else # include <ObjFWRT/ObjFWRT.h> # endif #endif #ifdef OF_APPLE_RUNTIME # include <objc/objc.h> # include <objc/runtime.h> # include <objc/message.h> #endif #if defined(__GNUC__) # define restrict __restrict__ #elif __STDC_VERSION__ < 199901L # define restrict #endif |
︙ | ︙ | |||
545 546 547 548 549 550 551 552 | # define OF_BSWAP64(i) \ (__builtin_constant_p(i) ? OF_BSWAP64_CONST(i) : OF_BSWAP64_NONCONST(i)) #else # define OF_BSWAP16(i) OF_BSWAP16_CONST(i) # define OF_BSWAP32(i) OF_BSWAP32_CONST(i) # define OF_BSWAP64(i) OF_BSWAP64_CONST(i) #endif | | | > > > > | > > > | | > > | > > | > > > > | | > | > > | > > > > > > < < < < | < < < < | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 | # define OF_BSWAP64(i) \ (__builtin_constant_p(i) ? OF_BSWAP64_CONST(i) : OF_BSWAP64_NONCONST(i)) #else # define OF_BSWAP16(i) OF_BSWAP16_CONST(i) # define OF_BSWAP32(i) OF_BSWAP32_CONST(i) # define OF_BSWAP64(i) OF_BSWAP64_CONST(i) #endif static OF_INLINE uint32_t OF_FLOAT_TO_INT_RAW(float f) { uint32_t ret; memcpy(&ret, &f, 4); return ret; } static OF_INLINE float OF_INT_TO_FLOAT_RAW(uint32_t uInt32) { float ret; memcpy(&ret, &uInt32, 4); return ret; } static OF_INLINE uint64_t OF_DOUBLE_TO_INT_RAW(double d) { uint64_t ret; memcpy(&ret, &d, 8); return ret; } static OF_INLINE double OF_INT_TO_DOUBLE_RAW(uint64_t uInt64) { double ret; memcpy(&ret, &uInt64, 8); return ret; } static OF_INLINE float OF_CONST_FUNC OF_BSWAP_FLOAT(float f) { return OF_INT_TO_FLOAT_RAW(OF_BSWAP32(OF_FLOAT_TO_INT_RAW(f))); } static OF_INLINE double OF_CONST_FUNC OF_BSWAP_DOUBLE(double d) { return OF_INT_TO_DOUBLE_RAW(OF_BSWAP64(OF_DOUBLE_TO_INT_RAW(d))); } #ifdef OF_BIG_ENDIAN # define OF_BSWAP16_IF_BE(i) OF_BSWAP16(i) # define OF_BSWAP32_IF_BE(i) OF_BSWAP32(i) # define OF_BSWAP64_IF_BE(i) OF_BSWAP64(i) # define OF_BSWAP16_IF_LE(i) (i) |
︙ | ︙ | |||
884 885 886 887 888 889 890 | struct timeval tv; gettimeofday(&tv, NULL); srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); return (((uint32_t)(rand()) << 16) | ((uint32_t)(rand()) & 0xFFFF)); #endif } | > > | 903 904 905 906 907 908 909 910 911 | 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 |
Modified src/objfw-defs.h.in from [96b18781fc] to [f12fccebb9].
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #undef OF_HAVE_BUILTIN_BSWAP32 #undef OF_HAVE_BUILTIN_BSWAP64 #undef OF_HAVE_CHMOD #undef OF_HAVE_CHOWN #undef OF_HAVE_FILES #undef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR #undef OF_HAVE_IPV6 #undef OF_HAVE_LIMITS_H #undef OF_HAVE_LINK #undef OF_HAVE_MAX_ALIGN_T #undef OF_HAVE_NETINET_IN_H #undef OF_HAVE_OSATOMIC #undef OF_HAVE_OSATOMIC_64 #undef OF_HAVE_PIPE #undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_PROCESSES #undef OF_HAVE_PTHREADS | > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #undef OF_HAVE_BUILTIN_BSWAP32 #undef OF_HAVE_BUILTIN_BSWAP64 #undef OF_HAVE_CHMOD #undef OF_HAVE_CHOWN #undef OF_HAVE_FILES #undef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR #undef OF_HAVE_IPV6 #undef OF_HAVE_IPX #undef OF_HAVE_LIMITS_H #undef OF_HAVE_LINK #undef OF_HAVE_MAX_ALIGN_T #undef OF_HAVE_NETINET_IN_H #undef OF_HAVE_NETINET_SCTP_H #undef OF_HAVE_NETINET_TCP_H #undef OF_HAVE_NETIPX_IPX_H #undef OF_HAVE_OSATOMIC #undef OF_HAVE_OSATOMIC_64 #undef OF_HAVE_PIPE #undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_PROCESSES #undef OF_HAVE_PTHREADS |
︙ | ︙ |
Modified src/of_asprintf.m from [04c9933717] to [cd42320784].
︙ | ︙ | |||
95 96 97 98 99 100 101 | } #endif #ifndef HAVE_ASPRINTF static int vasprintf(char **string, const char *format, va_list arguments) { | | | > > > > > > | | | > > > > > > > > > > > > > > > > > > > > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | } #endif #ifndef HAVE_ASPRINTF static int vasprintf(char **string, const char *format, va_list arguments) { int expectedLength, length; va_list argumentsCopy; va_copy(argumentsCopy, arguments); expectedLength = vsnprintf(NULL, 0, format, argumentsCopy); if (expectedLength == -1) /* * We have no way to know how large it is. Let's try 64 KB and * hope. */ expectedLength = 65535; if ((*string = malloc((size_t)expectedLength + 1)) == NULL) return -1; length = vsnprintf(*string, (size_t)expectedLength + 1, format, arguments); if (length == -1 || length > expectedLength) { free(*string); *string = NULL; return -1; } /* * In case we could not determine the size, resize to the actual size * needed, but ignore any failure to do so. */ if (length < expectedLength) { char *resized; if ((resized = realloc(*string, length + 1)) != NULL) *string = resized; } return length; } static int asprintf(char **string, const char *format, ...) { int ret; va_list arguments; |
︙ | ︙ | |||
276 277 278 279 280 281 282 | #endif ctx->lengthModifier = LENGTH_MODIFIER_J; break; case 'z': #if defined(OF_WINDOWS) | > | | > | | | 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | #endif ctx->lengthModifier = LENGTH_MODIFIER_J; break; case 'z': #if defined(OF_WINDOWS) if (sizeof(size_t) == 8) if (!appendSubformat(ctx, "I64", 3)) return false; #elif defined(_NEWLIB_VERSION) if (!appendSubformat(ctx, "l", 1)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->lengthModifier = LENGTH_MODIFIER_Z; break; case 't': #if defined(OF_WINDOWS) if (sizeof(ptrdiff_t) == 8) if (!appendSubformat(ctx, "I64", 3)) return false; #elif defined(_NEWLIB_VERSION) if (!appendSubformat(ctx, "l", 1)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif |
︙ | ︙ | |||
350 351 352 353 354 355 356 357 358 359 360 361 362 363 | } static bool formatConversionSpecifierState(struct context *ctx) { char *tmp = NULL; int tmpLen = 0; if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; switch (ctx->format[ctx->i]) { case '@': if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) | > > > | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | } static bool formatConversionSpecifierState(struct context *ctx) { char *tmp = NULL; int tmpLen = 0; #ifndef HAVE_ASPRINTF_L OFString *point; #endif if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; switch (ctx->format[ctx->i]) { case '@': if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) |
︙ | ︙ | |||
544 545 546 547 548 549 550 551 552 553 554 555 | va_arg(ctx->arguments, long double)); break; default: return false; } #ifndef HAVE_ASPRINTF_L /* * If there's no asprintf_l, we have no other choice than to * use this ugly hack to replace the locale's decimal point * back to ".". */ | > > > > > | < < < | | > > | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | va_arg(ctx->arguments, long double)); break; default: return false; } #ifndef HAVE_ASPRINTF_L if (tmpLen == -1) return false; /* * If there's no asprintf_l, we have no other choice than to * use this ugly hack to replace the locale's decimal point * back to ".". */ point = [OFLocale decimalPoint]; if (!ctx->useLocale && point != nil && ![point isEqual: @"."]) { void *pool = objc_autoreleasePoolPush(); char *tmp2; @try { OFMutableString *tmpStr = [OFMutableString stringWithUTF8String: tmp length: tmpLen]; [tmpStr replaceOccurrencesOfString: point withString: @"."]; if (tmpStr.UTF8StringLength > INT_MAX) return false; tmpLen = (int)tmpStr.UTF8StringLength; tmp2 = malloc(tmpLen); memcpy(tmp2, tmpStr.UTF8String, tmpLen); } @finally { free(tmp); objc_autoreleasePoolPop(pool); } |
︙ | ︙ |
Modified src/platform.h from [5334ff113e] to [40ddf7ef54].
︙ | ︙ | |||
86 87 88 89 90 91 92 | # endif # if defined(__mc68020__) || defined(OF_M68030) # define OF_M68020 # endif # if defined(__mc68010__) || defined(OF_M68020) # define OF_M68010 # endif | | | | | > > > | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | # endif # if defined(__mc68020__) || defined(OF_M68030) # define OF_M68020 # endif # if defined(__mc68010__) || defined(OF_M68020) # define OF_M68010 # endif #elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 # define OF_RISC_V_64 #elif defined(__riscv) # define OF_RISC_V #elif defined(__s390x__) # define OF_S390X #elif defined(__s390__) # define OF_S390 #endif #if defined(__APPLE__) # include <TargetConditionals.h> # if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ (defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR) # define OF_IOS |
︙ | ︙ |
Modified src/platform/posix/OFProcess.m from [bd118b08f1] to [a1d2451059].
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *path; char **argv; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; path = [program cStringWithEncoding: [OFLocale encoding]]; [self of_getArgv: &argv forProgramName: programName | > > > | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *path; char **argv; _pid = -1; _readPipe[0] = _writePipe[1] = -1; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; path = [program cStringWithEncoding: [OFLocale encoding]]; [self of_getArgv: &argv forProgramName: programName |
︙ | ︙ | |||
370 371 372 373 374 375 376 377 | } _pid = -1; _readPipe[0] = -1; [super close]; } @end | > > > > > > > > > > > > > | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | } _pid = -1; _readPipe[0] = -1; [super close]; } - (int)waitForTermination { if (_readPipe[0] == -1) @throw [OFNotOpenException exceptionWithObject: self]; if (_pid != -1) { waitpid(_pid, &_status, 0); _pid = -1; } return WEXITSTATUS(_status); } @end |
Modified src/platform/posix/thread.m from [537e06aaee] to [cdd7c510a1].
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | if (pthread_attr_getschedpolicy(&pattr, &policy) == 0) { minPrio = sched_get_priority_min(policy); maxPrio = sched_get_priority_max(policy); if (minPrio == -1 || maxPrio == -1) minPrio = maxPrio = 0; } if (pthread_attr_getschedparam(&pattr, ¶m) != 0) normalPrio = param.sched_priority; else minPrio = maxPrio = 0; pthread_attr_destroy(&pattr); | > < | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | if (pthread_attr_getschedpolicy(&pattr, &policy) == 0) { minPrio = sched_get_priority_min(policy); maxPrio = sched_get_priority_max(policy); if (minPrio == -1 || maxPrio == -1) minPrio = maxPrio = 0; } #endif if (pthread_attr_getschedparam(&pattr, ¶m) != 0) normalPrio = param.sched_priority; else minPrio = maxPrio = 0; pthread_attr_destroy(&pattr); } } static void * functionWrapper(void *data) { struct thread_ctx *ctx = data; |
︙ | ︙ |
Modified src/platform/windows/OFProcess.m from [0696e641e7] to [816ee6b0db].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #include "config.h" #include <errno.h> #include <string.h> #import "OFProcess.h" | | | | > > | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include "config.h" #include <errno.h> #include <string.h> #import "OFProcess.h" #import "OFArray.h" #import "OFData.h" #import "OFDictionary.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> @interface OFProcess () - (of_char16_t *)of_wideEnvironmentForDictionary: (OFDictionary *)dictionary; - (char *)of_environmentForDictionary: (OFDictionary *)environment; @end @implementation OFProcess + (instancetype)processWithProgram: (OFString *)program { return [[[self alloc] initWithProgram: program] autorelease]; } |
︙ | ︙ | |||
109 110 111 112 113 114 115 | environment: (OFDictionary *)environment { self = [super init]; @try { SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; | < | > | > | | > | | < < < < < < < | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | environment: (OFDictionary *)environment { self = [super init]; @try { SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; void *pool; OFMutableString *argumentsString; _process = INVALID_HANDLE_VALUE; _readPipe[0] = _writePipe[1] = NULL; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (!SetHandleInformation(_readPipe[0], HANDLE_FLAG_INHERIT, 0)) if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (!CreatePipe(&_writePipe[0], &_writePipe[1], &sa, 0)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (!SetHandleInformation(_writePipe[1], HANDLE_FLAG_INHERIT, 0)) if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) @throw [OFInitializationFailedException exceptionWithClass: self.class]; memset(&pi, 0, sizeof(pi)); pool = objc_autoreleasePoolPush(); argumentsString = [OFMutableString stringWithString: programName]; [argumentsString replaceOccurrencesOfString: @"\\\"" withString: @"\\\\\""]; |
︙ | ︙ | |||
180 181 182 183 184 185 186 | [argumentsString appendString: tmp]; if (containsSpaces) [argumentsString appendString: @"\""]; } | > > > > > > > > > > > > | > | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | [argumentsString appendString: tmp]; if (containsSpaces) [argumentsString appendString: @"\""]; } if ([OFSystemInfo isWindowsNT]) { size_t length; of_char16_t *argumentsCopy; STARTUPINFOW si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = _writePipe[0]; si.hStdOutput = _readPipe[1]; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; length = argumentsString.UTF16StringLength; argumentsCopy = [self allocMemoryWithSize: sizeof(of_char16_t) count: length + 1]; memcpy(argumentsCopy, argumentsString.UTF16String, (length + 1) * 2); @try { if (!CreateProcessW(program.UTF16String, argumentsCopy, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, [self of_wideEnvironmentForDictionary: environment], NULL, &si, &pi)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @finally { [self freeMemory: argumentsCopy]; } } else { of_string_encoding_t encoding = [OFLocale encoding]; STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = _writePipe[0]; si.hStdOutput = _readPipe[1]; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; if (!CreateProcessA([program cStringWithEncoding: encoding], (char *)[argumentsString cStringWithEncoding: encoding], NULL, NULL, TRUE, 0, [self of_environmentForDictionary: environment], NULL, &si, &pi)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } objc_autoreleasePoolPop(pool); _process = pi.hProcess; CloseHandle(pi.hThread); |
︙ | ︙ | |||
220 221 222 223 224 225 226 | { if (_readPipe[0] != NULL) [self close]; [super dealloc]; } | | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | { if (_readPipe[0] != NULL) [self close]; [super dealloc]; } - (of_char16_t *)of_wideEnvironmentForDictionary: (OFDictionary *)environment { OFMutableData *env; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; const of_char16_t equal = '='; const of_char16_t zero[2] = { 0, 0 }; |
︙ | ︙ | |||
248 249 250 251 252 253 254 255 256 257 258 259 260 261 | [env addItems: object.UTF16String count: object.UTF16StringLength]; [env addItems: &zero count: 1]; } [env addItems: zero count: 2]; return env.mutableItems; } - (bool)lowlevelIsAtEndOfStream { if (_readPipe[0] == NULL) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | [env addItems: object.UTF16String count: object.UTF16StringLength]; [env addItems: &zero count: 1]; } [env addItems: zero count: 2]; return env.mutableItems; } - (char *)of_environmentForDictionary: (OFDictionary *)environment { of_string_encoding_t encoding = [OFLocale encoding]; OFMutableData *env; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; if (environment == nil) return NULL; env = [OFMutableData data]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { [env addItems: [key cStringWithEncoding: encoding] count: [key cStringLengthWithEncoding: encoding]]; [env addItems: "=" count: 1]; [env addItems: [object cStringWithEncoding: encoding] count: [object cStringLengthWithEncoding: encoding]]; [env addItems: "" count: 1]; } [env addItems: "\0" count: 2]; return env.mutableItems; } - (bool)lowlevelIsAtEndOfStream { if (_readPipe[0] == NULL) |
︙ | ︙ | |||
341 342 343 344 345 346 347 348 | } _process = INVALID_HANDLE_VALUE; _readPipe[0] = NULL; [super close]; } @end | > > > > > > > > > > > > > > > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 | } _process = INVALID_HANDLE_VALUE; _readPipe[0] = NULL; [super close]; } - (int)waitForTermination { if (_readPipe[0] == NULL) @throw [OFNotOpenException exceptionWithObject: self]; if (_process != INVALID_HANDLE_VALUE) { DWORD exitCode; WaitForSingleObject(_process, INFINITE); if (GetExitCodeProcess(_process, &exitCode)) _status = exitCode; else _status = GetLastError(); CloseHandle(_process); _process = INVALID_HANDLE_VALUE; } return _status; } @end |
Modified src/runtime/linklib/linklib.m from [570378ad75] to [141357802d].
︙ | ︙ | |||
59 60 61 62 63 64 65 | #endif extern void __register_frame_info(const void *, void *); extern void *__deregister_frame_info(const void *); struct Library *ObjFWRTBase; void *__objc_class_name_Protocol; | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #endif extern void __register_frame_info(const void *, void *); extern void *__deregister_frame_info(const void *); struct Library *ObjFWRTBase; void *__objc_class_name_Protocol; static void __attribute__((__used__)) ctor(void) { static bool initialized = false; struct objc_libc libc = { .malloc = malloc, .calloc = calloc, .realloc = realloc, |
︙ | ︙ | |||
112 113 114 115 116 117 118 | fputs("Failed to initialize " OBJFWRT_AMIGA_LIB "!\n", stderr); abort(); } initialized = true; } | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | fputs("Failed to initialize " OBJFWRT_AMIGA_LIB "!\n", stderr); abort(); } initialized = true; } static void __attribute__((__used__)) dtor(void) { CloseLibrary(ObjFWRTBase); } #if defined(OF_AMIGAOS_M68K) ADD2INIT(ctor, -2); |
︙ | ︙ |
Modified src/socket.h from [d2c0976e15] to [b3045e055c].
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #endif #ifdef OF_HAVE_NETINET_IN_H # include <netinet/in.h> #endif #ifdef OF_HAVE_NETINET_TCP_H # include <netinet/tcp.h> #endif #include "platform.h" #ifdef OF_WINDOWS # include <windows.h> # include <ws2tcpip.h> #endif /*! @file */ #ifdef OF_WII # include <network.h> #endif | > > > > > > > > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #endif #ifdef OF_HAVE_NETINET_IN_H # include <netinet/in.h> #endif #ifdef OF_HAVE_NETINET_TCP_H # include <netinet/tcp.h> #endif #ifdef OF_HAVE_NETINET_SCTP_H # include <netinet/sctp.h> #endif #ifdef OF_HAVE_NETIPX_IPX_H # include <netipx/ipx.h> #endif #include "platform.h" #ifdef OF_WINDOWS # include <windows.h> # include <ws2tcpip.h> # ifdef OF_HAVE_IPX # include <wsipx.h> # endif #endif /*! @file */ #ifdef OF_WII # include <network.h> #endif |
︙ | ︙ | |||
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | typedef enum { /** An unknown address family. */ OF_SOCKET_ADDRESS_FAMILY_UNKNOWN, /** IPv4 */ OF_SOCKET_ADDRESS_FAMILY_IPV4, /** IPv6 */ OF_SOCKET_ADDRESS_FAMILY_IPV6, /** Any address family */ OF_SOCKET_ADDRESS_FAMILY_ANY = 255 } of_socket_address_family_t; #ifndef OF_HAVE_IPV6 struct sockaddr_in6 { sa_family_t sin6_family; in_port_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr { uint8_t s6_addr[16]; } sin6_addr; uint32_t sin6_scope_id; }; #endif /*! * @struct of_socket_address_t socket.h ObjFW/socket.h * * @brief A struct which represents a host / port pair for a socket. */ | > > > > > > > > > > > > > > > > > > > > | > > | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | typedef enum { /** An unknown address family. */ OF_SOCKET_ADDRESS_FAMILY_UNKNOWN, /** IPv4 */ OF_SOCKET_ADDRESS_FAMILY_IPV4, /** IPv6 */ OF_SOCKET_ADDRESS_FAMILY_IPV6, /** IPX */ OF_SOCKET_ADDRESS_FAMILY_IPX, /** Any address family */ OF_SOCKET_ADDRESS_FAMILY_ANY = 255 } of_socket_address_family_t; #ifndef OF_HAVE_IPV6 struct sockaddr_in6 { sa_family_t sin6_family; in_port_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr { uint8_t s6_addr[16]; } sin6_addr; uint32_t sin6_scope_id; }; #endif #ifndef OF_HAVE_IPX # define IPX_NODE_LEN 6 struct sockaddr_ipx { sa_family_t sipx_family; uint32_t sipx_network; unsigned char sipx_node[IPX_NODE_LEN]; uint16_t sipx_port; uint8_t sipx_type; }; #endif #ifdef OF_WINDOWS # define IPX_NODE_LEN 6 # define sipx_family sa_family # 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 { /* * Even though struct sockaddr contains the family, we need to use our * own family, as we need to support storing an IPv6 address on systems * that don't support IPv6. These may not have AF_INET6 defined and we * can't just define it, as the value is system-dependent and might * clash with an existing value. */ of_socket_address_family_t family; union { struct sockaddr sockaddr; struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_ipx ipx; } sockaddr; socklen_t length; }; 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. * |
︙ | ︙ | |||
146 147 148 149 150 151 152 | * @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); | < | > > > > > > > > > > | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | * @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 */ 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 |
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 | * * @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); extern bool of_socket_init(void); #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) extern void of_socket_deinit(void); #endif extern int of_socket_errno(void); #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | * * @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 */ extern void of_socket_address_get_ipx_node( const of_socket_address_t *_Nonnull address, unsigned char node[_Nonnull IPX_NODE_LEN]); extern bool of_socket_init(void); #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) extern void of_socket_deinit(void); #endif extern int of_socket_errno(void); #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr, |
︙ | ︙ |
Modified src/socket.m from [353f4118f9] to [fb89efec65].
︙ | ︙ | |||
342 343 344 345 346 347 348 | return ret; } #endif of_socket_address_t of_socket_address_parse_ipv4(OFString *IPv4, uint16_t port) { | < < | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | return ret; } #endif of_socket_address_t of_socket_address_parse_ipv4(OFString *IPv4, uint16_t port) { void *pool = objc_autoreleasePoolPush(); OFCharacterSet *whitespaceCharacterSet = [OFCharacterSet whitespaceCharacterSet]; of_socket_address_t ret; struct sockaddr_in *addrIn = &ret.sockaddr.in; OFArray OF_GENERIC(OFString *) *components; uint32_t addr; |
︙ | ︙ | |||
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | { @try { return of_socket_address_parse_ipv6(IP, port); } @catch (OFInvalidFormatException *e) { return of_socket_address_parse_ipv4(IP, port); } } bool of_socket_address_equal(const of_socket_address_t *address1, const of_socket_address_t *address2) { const struct sockaddr_in *addrIn1, *addrIn2; const struct sockaddr_in6 *addrIn6_1, *addrIn6_2; if (address1->family != address2->family) return false; switch (address1->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) | > > > > > > > > > > > > > > > > > > > > > > > > > | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | { @try { return of_socket_address_parse_ipv6(IP, port); } @catch (OFInvalidFormatException *e) { return of_socket_address_parse_ipv4(IP, port); } } of_socket_address_t of_socket_address_ipx(const unsigned char node[IPX_NODE_LEN], uint32_t network, uint16_t port) { of_socket_address_t ret; memset(&ret, '\0', sizeof(ret)); ret.family = OF_SOCKET_ADDRESS_FAMILY_IPX; ret.length = sizeof(ret.sockaddr.ipx); #ifdef AF_IPX ret.sockaddr.ipx.sipx_family = AF_IPX; #else ret.sockaddr.ipx.sipx_family = AF_UNSPEC; #endif memcpy(ret.sockaddr.ipx.sipx_node, node, IPX_NODE_LEN); network = OF_BSWAP32_IF_LE(network); memcpy(&ret.sockaddr.ipx.sipx_network, &network, sizeof(ret.sockaddr.ipx.sipx_network)); ret.sockaddr.ipx.sipx_port = OF_BSWAP16_IF_LE(port); return ret; } bool of_socket_address_equal(const of_socket_address_t *address1, const of_socket_address_t *address2) { const struct sockaddr_in *addrIn1, *addrIn2; const struct sockaddr_in6 *addrIn6_1, *addrIn6_2; const struct sockaddr_ipx *addrIPX1, *addrIPX2; if (address1->family != address2->family) return false; switch (address1->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) |
︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 | if (addrIn6_1->sin6_port != addrIn6_2->sin6_port) return false; if (memcmp(addrIn6_1->sin6_addr.s6_addr, addrIn6_2->sin6_addr.s6_addr, sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0) return false; break; default: @throw [OFInvalidArgumentException exception]; } return true; } | > > > > > > > > > > > > > > > > > > | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | if (addrIn6_1->sin6_port != addrIn6_2->sin6_port) return false; if (memcmp(addrIn6_1->sin6_addr.s6_addr, addrIn6_2->sin6_addr.s6_addr, sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0) return false; break; case OF_SOCKET_ADDRESS_FAMILY_IPX: if (address1->length < (socklen_t)sizeof(struct sockaddr_ipx) || address2->length < (socklen_t)sizeof(struct sockaddr_ipx)) @throw [OFInvalidArgumentException exception]; addrIPX1 = &address1->sockaddr.ipx; addrIPX2 = &address2->sockaddr.ipx; if (addrIPX1->sipx_port != addrIPX2->sipx_port) return false; if (memcmp(&addrIPX1->sipx_network, &addrIPX2->sipx_network, 4) != 0) return false; if (memcmp(addrIPX1->sipx_node, addrIPX2->sipx_node, IPX_NODE_LEN) != 0) return false; break; default: @throw [OFInvalidArgumentException exception]; } return true; } |
︙ | ︙ | |||
597 598 599 600 601 602 603 604 605 606 607 608 609 610 | OF_HASH_ADD(hash, address->sockaddr.in6.sin6_port); for (size_t i = 0; i < sizeof(address->sockaddr.in6.sin6_addr.s6_addr); i++) OF_HASH_ADD(hash, address->sockaddr.in6.sin6_addr.s6_addr[i]); break; default: @throw [OFInvalidArgumentException exception]; } OF_HASH_FINALIZE(hash); | > > > > > > > > > > > > > > > > > > > > | 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | OF_HASH_ADD(hash, address->sockaddr.in6.sin6_port); for (size_t i = 0; i < sizeof(address->sockaddr.in6.sin6_addr.s6_addr); i++) OF_HASH_ADD(hash, address->sockaddr.in6.sin6_addr.s6_addr[i]); break; case OF_SOCKET_ADDRESS_FAMILY_IPX:; unsigned char network[ sizeof(address->sockaddr.ipx.sipx_network)]; if (address->length < (socklen_t)sizeof(struct sockaddr_ipx)) @throw [OFInvalidArgumentException exception]; OF_HASH_ADD(hash, address->sockaddr.ipx.sipx_port >> 8); OF_HASH_ADD(hash, address->sockaddr.ipx.sipx_port); memcpy(network, &address->sockaddr.ipx.sipx_network, sizeof(network)); for (size_t i = 0; i < sizeof(network); i++) OF_HASH_ADD(hash, network[i]); for (size_t i = 0; i < IPX_NODE_LEN; i++) OF_HASH_ADD(hash, address->sockaddr.ipx.sipx_node[i]); break; default: @throw [OFInvalidArgumentException exception]; } OF_HASH_FINALIZE(hash); |
︙ | ︙ | |||
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 | switch (address->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: address->sockaddr.in.sin_port = OF_BSWAP16_IF_LE(port); break; case OF_SOCKET_ADDRESS_FAMILY_IPV6: address->sockaddr.in6.sin6_port = OF_BSWAP16_IF_LE(port); break; default: @throw [OFInvalidArgumentException exception]; } } uint16_t of_socket_address_get_port(const of_socket_address_t *address) { switch (address->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: return OF_BSWAP16_IF_LE(address->sockaddr.in.sin_port); case OF_SOCKET_ADDRESS_FAMILY_IPV6: return OF_BSWAP16_IF_LE(address->sockaddr.in6.sin6_port); default: @throw [OFInvalidArgumentException exception]; } } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 | switch (address->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: address->sockaddr.in.sin_port = OF_BSWAP16_IF_LE(port); break; case OF_SOCKET_ADDRESS_FAMILY_IPV6: address->sockaddr.in6.sin6_port = OF_BSWAP16_IF_LE(port); break; case OF_SOCKET_ADDRESS_FAMILY_IPX: address->sockaddr.ipx.sipx_port = OF_BSWAP16_IF_LE(port); break; default: @throw [OFInvalidArgumentException exception]; } } uint16_t of_socket_address_get_port(const of_socket_address_t *address) { switch (address->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: return OF_BSWAP16_IF_LE(address->sockaddr.in.sin_port); case OF_SOCKET_ADDRESS_FAMILY_IPV6: return OF_BSWAP16_IF_LE(address->sockaddr.in6.sin6_port); case OF_SOCKET_ADDRESS_FAMILY_IPX: return OF_BSWAP16_IF_LE(address->sockaddr.ipx.sipx_port); default: @throw [OFInvalidArgumentException exception]; } } void of_socket_address_set_ipx_network(of_socket_address_t *address, uint32_t network) { if (address->family != OF_SOCKET_ADDRESS_FAMILY_IPX) @throw [OFInvalidArgumentException exception]; network = OF_BSWAP32_IF_LE(network); memcpy(&address->sockaddr.ipx.sipx_network, &network, sizeof(address->sockaddr.ipx.sipx_network)); } uint32_t of_socket_address_get_ipx_network(const of_socket_address_t *address) { uint32_t network; if (address->family != OF_SOCKET_ADDRESS_FAMILY_IPX) @throw [OFInvalidArgumentException exception]; memcpy(&network, &address->sockaddr.ipx.sipx_network, sizeof(network)); return OF_BSWAP32_IF_LE(network); } void of_socket_address_set_ipx_node(of_socket_address_t *address, const unsigned char node[IPX_NODE_LEN]) { if (address->family != OF_SOCKET_ADDRESS_FAMILY_IPX) @throw [OFInvalidArgumentException exception]; memcpy(address->sockaddr.ipx.sipx_node, node, IPX_NODE_LEN); } void of_socket_address_get_ipx_node(const of_socket_address_t *address, unsigned char node[IPX_NODE_LEN]) { if (address->family != OF_SOCKET_ADDRESS_FAMILY_IPX) @throw [OFInvalidArgumentException exception]; memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN); } |
Modified src/unicode.m from [910afd7d8b] to [8d99c0a504].
︙ | ︙ | |||
639 640 641 642 643 644 645 646 647 648 649 | 0, 42896, 0, 42898, 42948, 0, 0, 42902, 0, 42904, 0, 42906, 0, 42908, 0, 42910, 0, 42912, 0, 42914, 0, 42916, 0, 42918, 0, 42920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42932, 0, 42934, 0, 42936, 0, 42938, 0, 42940, 0, 42942, 0, 0, 0, 42946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | > | < | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 | 0, 42896, 0, 42898, 42948, 0, 0, 42902, 0, 42904, 0, 42906, 0, 42908, 0, 42910, 0, 42912, 0, 42914, 0, 42916, 0, 42918, 0, 42920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42932, 0, 42934, 0, 42936, 0, 42938, 0, 42940, 0, 42942, 0, 0, 0, 42946, 0, 0, 0, 0, 42951, 0, 42953, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42997, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const of_unichar_t uppercasePage171[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1443 1444 1445 1446 1447 1448 1449 | 0, 0, 0, 42892, 0, 613, 0, 0, 42897, 0, 42899, 0, 0, 0, 42903, 0, 42905, 0, 42907, 0, 42909, 0, 42911, 0, 42913, 0, 42915, 0, 42917, 0, 42919, 0, 42921, 0, 614, 604, 609, 620, 618, 0, 670, 647, 669, 43859, 42933, 0, 42935, 0, 42937, 0, 42939, 0, 42941, 0, 42943, 0, | | > | < | 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | 0, 0, 0, 42892, 0, 613, 0, 0, 42897, 0, 42899, 0, 0, 0, 42903, 0, 42905, 0, 42907, 0, 42909, 0, 42911, 0, 42913, 0, 42915, 0, 42917, 0, 42919, 0, 42921, 0, 614, 604, 609, 620, 618, 0, 670, 647, 669, 43859, 42933, 0, 42935, 0, 42937, 0, 42939, 0, 42941, 0, 42943, 0, 0, 0, 42947, 0, 42900, 642, 7566, 42952, 0, 42954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42998, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const of_unichar_t lowercasePage255[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; static const char *const decompositionPage465[0x100] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; static const char *const decompositionPage281[0x100] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xF0\x91\xA4\xB5\xF0\x91\xA4\xB0", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; static const char *const decompositionPage465[0x100] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
︙ | ︙ | |||
10319 10320 10321 10322 10323 10324 10325 | NULL, NULL, "\xEA\x9C\xA7", "\xEA\xAC\xB7", "\xC9\xAB", "\xEA\xAD\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | | | 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 | NULL, NULL, "\xEA\x9C\xA7", "\xEA\xAC\xB7", "\xC9\xAB", "\xEA\xAD\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xCA\x8D", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
︙ | ︙ | |||
12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111 12112 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; const of_unichar_t *const of_unicode_uppercase_table[0x1EA] = { uppercasePage0, uppercasePage1, uppercasePage2, uppercasePage3, uppercasePage4, uppercasePage5, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage16, emptyPage, emptyPage, uppercasePage19, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; static const char *const decompCompatPage507[0x100] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\x30", "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37", "\x38", "\x39", NULL, NULL, NULL, NULL, NULL, NULL, }; const of_unichar_t *const of_unicode_uppercase_table[0x1EA] = { uppercasePage0, uppercasePage1, uppercasePage2, uppercasePage3, uppercasePage4, uppercasePage5, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage16, emptyPage, emptyPage, uppercasePage19, |
︙ | ︙ | |||
12739 12740 12741 12742 12743 12744 12745 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage272, decompositionPage273, emptyDecompositionPage, decompositionPage275, decompositionPage276, decompositionPage277, emptyDecompositionPage, | | | 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013 13014 13015 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage272, decompositionPage273, emptyDecompositionPage, decompositionPage275, decompositionPage276, decompositionPage277, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage281, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, |
︙ | ︙ | |||
12997 12998 12999 13000 13001 13002 13003 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage272, decompositionPage273, emptyDecompositionPage, decompositionPage275, decompositionPage276, decompositionPage277, emptyDecompositionPage, | | | 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage272, decompositionPage273, emptyDecompositionPage, decompositionPage275, decompositionPage276, decompositionPage277, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage281, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, |
︙ | ︙ | |||
13073 13074 13075 13076 13077 13078 13079 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompCompatPage494, emptyDecompositionPage, emptyDecompositionPage, decompCompatPage497, decompCompatPage498, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, | | | 13335 13336 13337 13338 13339 13340 13341 13342 13343 13344 13345 13346 13347 13348 13349 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompCompatPage494, emptyDecompositionPage, emptyDecompositionPage, decompCompatPage497, decompCompatPage498, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompCompatPage507, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, |
︙ | ︙ |
Modified tests/Makefile from [c5b865857f] to [34b62fa1a0].
1 2 3 4 5 6 7 8 9 10 11 12 13 | include ../extra.mk SUBDIRS = ${TESTPLUGIN} CLEAN = EBOOT.PBP \ boot.dol \ ${PROG_NOINST}.arm9 \ ${PROG_NOINST}.nds PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ OFArrayTests.m \ | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | include ../extra.mk SUBDIRS = ${TESTPLUGIN} CLEAN = EBOOT.PBP \ boot.dol \ ${PROG_NOINST}.arm9 \ ${PROG_NOINST}.nds PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ OFArrayTests.m \ ${OF_BLOCK_TESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDateTests.m \ OFDictionaryTests.m \ OFInvocationTests.m \ OFJSONTests.m \ OFListTests.m \ |
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 | OFRIPEMD160HashTests.m \ OFSerializationTests.m \ OFSHA1HashTests.m \ OFSHA224HashTests.m \ OFSHA256HashTests.m \ OFSHA384HashTests.m \ OFSHA512HashTests.m SRCS_PLUGINS = OFPluginTests.m SRCS_SOCKETS = OFDNSResolverTests.m \ | > > > > | | > > | | | | | | | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | OFRIPEMD160HashTests.m \ OFSerializationTests.m \ OFSHA1HashTests.m \ OFSHA224HashTests.m \ OFSHA256HashTests.m \ OFSHA384HashTests.m \ OFSHA512HashTests.m SRCS_IPX = OFIPXSocketTests.m \ OFSPXSocketTests.m \ OFSPXStreamSocketTests.m SRCS_PLUGINS = OFPluginTests.m SRCS_SCTP = OFSCTPSocketTests.m SRCS_SOCKETS = OFDNSResolverTests.m \ ${OF_HTTP_CLIENT_TESTS_M} \ OFHTTPCookieTests.m \ OFHTTPCookieManagerTests.m \ OFKernelEventObserverTests.m \ OFTCPSocketTests.m \ OFUDPSocketTests.m \ SocketTests.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_SCTP} SRCS_THREADS = OFThreadTests.m SRCS_WINDOWS = OFWindowsRegistryKeyTests.m IOS_USER ?= mobile IOS_TMP ?= /tmp/objfw-test include ../buildsys.mk post-all: ${RUN_TESTS} .PHONY: run run-on-ios run-on-android run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt.dll libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../src/libobjfw.so; then \ ${LN_S} ../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../src/objfw.dll; then \ ${LN_S} ../src/objfw.dll objfw.dll; \ fi if test -f ../src/libobjfw.dylib; then \ ${LN_S} ../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../src/runtime/libobjfwrt.so; then \ ${LN_S} ../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../src/runtime/objfwrt.dll; then \ ${LN_S} ../src/runtime/objfwrt.dll objfwrt.dll; \ fi if test -f ../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_FRAMEWORK_PATH=../src:../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \ 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.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f objfwrt.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 \ echo "Please set IOS_HOST to the hostname of your iOS host!"; \ exit 1; \ |
︙ | ︙ |
Modified tests/OFDNSResolverTests.m from [d86ca4b2a2] to [8f7194537b].
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | @implementation TestsAppDelegate (OFDNSResolverTests) - (void)DNSResolverTests { void *pool = objc_autoreleasePoolPush(); OFDNSResolver *resolver = [OFDNSResolver resolver]; OFMutableString *staticHosts = [OFMutableString string]; for (OFString *host in resolver.staticHosts) { OFString *IPs; if (staticHosts.length > 0) [staticHosts appendString: @"; "]; IPs = [[resolver.staticHosts objectForKey: host] componentsJoinedByString: @", "]; [staticHosts appendFormat: @"%@=(%@)", host, IPs]; } | > > > | | | > | | | > | > | > | | > | > | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | @implementation TestsAppDelegate (OFDNSResolverTests) - (void)DNSResolverTests { void *pool = objc_autoreleasePoolPush(); OFDNSResolver *resolver = [OFDNSResolver resolver]; OFMutableString *staticHosts = [OFMutableString string]; of_stdout.foregroundColor = [OFColor lime]; for (OFString *host in resolver.staticHosts) { OFString *IPs; if (staticHosts.length > 0) [staticHosts appendString: @"; "]; IPs = [[resolver.staticHosts objectForKey: host] componentsJoinedByString: @", "]; [staticHosts appendFormat: @"%@=(%@)", host, IPs]; } [of_stdout writeFormat: @"[OFDNSResolver] Static hosts: %@\n", staticHosts]; [of_stdout writeFormat: @"[OFDNSResolver] Name servers: %@\n", [resolver.nameServers componentsJoinedByString: @", "]]; [of_stdout writeFormat: @"[OFDNSResolver] Local domain: %@\n", resolver.localDomain]; [of_stdout writeFormat: @"[OFDNSResolver] Search domains: %@\n", [resolver.searchDomains componentsJoinedByString: @", "]]; [of_stdout writeFormat: @"[OFDNSResolver] Timeout: %lf\n", resolver.timeout]; [of_stdout writeFormat: @"[OFDNSResolver] Max attempts: %u\n", resolver.maxAttempts]; [of_stdout writeFormat: @"[OFDNSResolver] Min number of dots in absolute name: %u\n", resolver.minNumberOfDotsInAbsoluteName]; [of_stdout writeFormat: @"[OFDNSResolver] Uses TCP: %u\n", module, resolver.usesTCP]; [of_stdout writeFormat: @"[OFDNSResolver] Config reload interval: %lf\n", resolver.configReloadInterval]; objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFDateTests.m from [e04db68127] to [3f9f2f2e15].
︙ | ︙ | |||
53 54 55 56 57 58 59 | isEqual: @"2000-06-20T10:34:56Z"]); EXPECT_EXCEPTION(@"Detection of unparsed in " @"+[dateWithDateString:format:]", OFInvalidFormatException, [OFDate dateWithDateString: @"2000-06-20T12:34:56+0200x" format: @"%Y-%m-%dT%H:%M:%S%z"]) | < > | | > > | | > > > > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | isEqual: @"2000-06-20T10:34:56Z"]); EXPECT_EXCEPTION(@"Detection of unparsed in " @"+[dateWithDateString:format:]", OFInvalidFormatException, [OFDate dateWithDateString: @"2000-06-20T12:34:56+0200x" format: @"%Y-%m-%dT%H:%M:%S%z"]) TEST(@"+[dateWithLocalDateString:format:]", [[[OFDate dateWithLocalDateString: @"2000-06-20T12:34:56" format: @"%Y-%m-%dT%H:%M:%S"] localDateStringWithFormat: @"%Y-%m-%dT%H:%M:%S"] isEqual: @"2000-06-20T12:34:56"]); TEST(@"+[dateWithLocalDateString:format:]", [[[OFDate dateWithLocalDateString: @"2000-06-20T12:34:56-0200" format: @"%Y-%m-%dT%H:%M:%S%z"] description] isEqual: @"2000-06-20T14:34:56Z"]); EXPECT_EXCEPTION(@"Detection of unparsed in " @"+[dateWithLocalDateString:format:] #1", OFInvalidFormatException, [OFDate dateWithLocalDateString: @"2000-06-20T12:34:56x" format: @"%Y-%m-%dT%H:%M:%S"]) EXPECT_EXCEPTION(@"Detection of unparsed in " @"+[dateWithLocalDateString:format:] #2", OFInvalidFormatException, [OFDate dateWithLocalDateString: @"2000-06-20T12:34:56+0200x" format: @"%Y-%m-%dT%H:%M:%S%z"]) TEST(@"-[isEqual:]", [d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0]] && ![d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0.0000001]]) |
︙ | ︙ |
Added tests/OFIPXSocketTests.m version [7578ebb381].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #import "TestsAppDelegate.h" static OFString *module = @"OFIPXSocket"; @implementation TestsAppDelegate (OFIPXSocketTests) - (void)IPXSocketTests { void *pool = objc_autoreleasePoolPush(); OFIPXSocket *sock; of_socket_address_t address1, address2; char buffer[5]; TEST(@"+[socket]", (sock = [OFIPXSocket socket])) @try { TEST(@"-[bindToPort:packetType:]", R(address1 = [sock bindToPort: 0 packetType: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFIPXSocket] -[bindToPort:packetType:]: " @"IPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFIPXSocket] -[bindToPort:packetType:]: " @"IPX not configured, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } TEST(@"-[sendBuffer:length:receiver:]", R([sock sendBuffer: "Hello" length: 5 receiver: &address1])) TEST(@"-[receiveIntoBuffer:length:sender:]", [sock receiveIntoBuffer: buffer length: 5 sender: &address2] == 5 && memcmp(buffer, "Hello", 5) == 0 && of_socket_address_equal(&address1, &address2) && of_socket_address_hash(&address1) == of_socket_address_hash(&address2)) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFLocaleTests.m from [bc413d1703] to [bba7d2e3cd].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #include "config.h" #import "TestsAppDelegate.h" | < < > > > | > | | | > | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | * file. */ #include "config.h" #import "TestsAppDelegate.h" @implementation TestsAppDelegate (OFLocaleTests) - (void)localeTests { void *pool = objc_autoreleasePoolPush(); of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeFormat: @"[OFLocale]: Language: %@\n", [OFLocale language]]; [of_stdout writeFormat: @"[OFLocale]: Territory: %@\n", [OFLocale territory]]; [of_stdout writeFormat: @"[OFLocale]: Encoding: %@\n", of_string_name_of_encoding([OFLocale encoding])]; [of_stdout writeFormat: @"[OFLocale]: Decimal point: %@\n", [OFLocale decimalPoint]]; objc_autoreleasePoolPop(pool); } @end |
Added tests/OFSCTPSocketTests.m version [42f1cba28c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #include <string.h> #import "TestsAppDelegate.h" static OFString *module = @"OFSCTPSocket"; @implementation TestsAppDelegate (OFSCTPSocketTests) - (void)SCTPSocketTests { void *pool = objc_autoreleasePoolPush(); OFSCTPSocket *server, *client = nil, *accepted; uint16_t port; char buf[6]; TEST(@"+[socket]", (server = [OFSCTPSocket socket]) && (client = [OFSCTPSocket socket])) @try { TEST(@"-[bindToHost:port:]", (port = [server bindToHost: @"127.0.0.1" port: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EPROTONOSUPPORT: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSCTPSocket] -[bindToHost:port:]: " @"SCTP unsupported, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } TEST(@"-[listen]", R([server listen])) TEST(@"-[connectToHost:port:]", R([client connectToHost: @"127.0.0.1" port: port])) TEST(@"-[accept]", (accepted = [server accept])) TEST(@"-[remoteAddress]", [of_socket_address_ip_string(accepted.remoteAddress, NULL) isEqual: @"127.0.0.1"]) TEST(@"-[sendBuffer:length:]", R([client sendBuffer: "Hello!" length: 6])) TEST(@"-[receiveIntoBuffer:length:]", [accepted receiveIntoBuffer: buf length: 6] && !memcmp(buf, "Hello!", 6)) objc_autoreleasePoolPop(pool); } @end |
Added tests/OFSPXSocketTests.m version [6d42db054f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #import "TestsAppDelegate.h" static OFString *module = @"OFSPXSocket"; @interface SPXSocketDelegate: OFObject <OFSPXSocketDelegate> { @public OFSequencedPacketSocket *_expectedServerSocket; OFSPXSocket *_expectedClientSocket; unsigned char _expectedNode[IPX_NODE_LEN]; uint32_t _expectedNetwork; uint16_t _expectedPort; bool _accepted; bool _connected; } @end @implementation SPXSocketDelegate - (bool)socket: (OFSequencedPacketSocket *)sock didAcceptSocket: (OFSequencedPacketSocket *)accepted exception: (id)exception { OF_ENSURE(!_accepted); _accepted = (sock == _expectedServerSocket && accepted != nil && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; return false; } - (void)socket: (OFSPXSocket *)sock didConnectToNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port exception: (id)exception { OF_ENSURE(!_connected); _connected = (sock == _expectedClientSocket && memcmp(node, _expectedNode, IPX_NODE_LEN) == 0 && network == _expectedNetwork && port == _expectedPort && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; } @end @implementation TestsAppDelegate (OFSPXSocketTests) - (void)SPXSocketTests { void *pool = objc_autoreleasePoolPush(); OFSPXSocket *sockClient, *sockServer, *sockAccepted;; of_socket_address_t address1; const of_socket_address_t *address2; unsigned char node[IPX_NODE_LEN], node2[IPX_NODE_LEN]; uint32_t network; uint16_t port; char buffer[5]; SPXSocketDelegate *delegate; TEST(@"+[socket]", (sockClient = [OFSPXSocket socket]) && (sockServer = [OFSPXSocket socket])) @try { TEST(@"-[bindToPort:]", R(address1 = [sockServer bindToPort: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSPXSocket] -[bindToPort:]: " @"IPX unsupported, skipping tests"]; break; case ESOCKTNOSUPPORT: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSPXSocket] -[bindToPort:]: " @"SPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSPXSocket] -[bindToPort:]: " @"IPX not configured, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } of_socket_address_get_ipx_node(&address1, node); network = of_socket_address_get_ipx_network(&address1); port = of_socket_address_get_port(&address1); TEST(@"-[listen]", R([sockServer listen])) TEST(@"-[connectToNode:network:port:]", R([sockClient connectToNode: node network: network port: port])) TEST(@"-[accept]", (sockAccepted = [sockServer accept])) TEST(@"-[sendBuffer:length:]", R([sockAccepted sendBuffer: "Hello" length: 5])) TEST(@"-[receiveIntoBuffer:length:]", [sockClient receiveIntoBuffer: buffer length: 5] == 5 && memcmp(buffer, "Hello", 5) == 0) TEST(@"-[remoteAddress]", (address2 = sockAccepted.remoteAddress) && R(of_socket_address_get_ipx_node(address2, node2)) && memcmp(node, node2, IPX_NODE_LEN) == 0 && of_socket_address_get_ipx_network(address2) == network) delegate = [[[SPXSocketDelegate alloc] init] autorelease]; sockServer = [OFSPXSocket socket]; delegate->_expectedServerSocket = sockServer; sockServer.delegate = delegate; sockClient = [OFSPXSocket socket]; delegate->_expectedClientSocket = sockClient; sockClient.delegate = delegate; address1 = [sockServer bindToPort: 0]; [sockServer listen]; [sockServer asyncAccept]; of_socket_address_get_ipx_node(&address1, node); memcpy(delegate->_expectedNode, node, IPX_NODE_LEN); delegate->_expectedNetwork = network = of_socket_address_get_ipx_network(&address1); delegate->_expectedPort = port = of_socket_address_get_port(&address1); [sockClient asyncConnectToNode: node network: network port: port]; [[OFRunLoop mainRunLoop] runUntilDate: [OFDate dateWithTimeIntervalSinceNow: 2]]; TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]", delegate->_accepted && delegate->_connected) objc_autoreleasePoolPop(pool); } @end |
Added tests/OFSPXStreamSocketTests.m version [c4c06acd4d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <errno.h> #import "TestsAppDelegate.h" static OFString *module = @"OFSPXStreamSocket"; @interface SPXStreamSocketDelegate: OFObject <OFSPXStreamSocketDelegate> { @public OFStreamSocket *_expectedServerSocket; OFSPXStreamSocket *_expectedClientSocket; unsigned char _expectedNode[IPX_NODE_LEN]; uint32_t _expectedNetwork; uint16_t _expectedPort; bool _accepted; bool _connected; } @end @implementation SPXStreamSocketDelegate - (bool)socket: (OFStreamSocket *)sock didAcceptSocket: (OFStreamSocket *)accepted exception: (id)exception { OF_ENSURE(!_accepted); _accepted = (sock == _expectedServerSocket && accepted != nil && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; return false; } - (void)socket: (OFSPXStreamSocket *)sock didConnectToNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port exception: (id)exception { OF_ENSURE(!_connected); _connected = (sock == _expectedClientSocket && memcmp(node, _expectedNode, IPX_NODE_LEN) == 0 && network == _expectedNetwork && port == _expectedPort && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; } @end @implementation TestsAppDelegate (OFSPXStreamSocketTests) - (void)SPXStreamSocketTests { void *pool = objc_autoreleasePoolPush(); OFSPXStreamSocket *sockClient, *sockServer, *sockAccepted;; of_socket_address_t address1; const of_socket_address_t *address2; unsigned char node[IPX_NODE_LEN], node2[IPX_NODE_LEN]; uint32_t network; uint16_t port; char buffer[5]; SPXStreamSocketDelegate *delegate; TEST(@"+[socket]", (sockClient = [OFSPXStreamSocket socket]) && (sockServer = [OFSPXStreamSocket socket])) @try { TEST(@"-[bindToPort:]", R(address1 = [sockServer bindToPort: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[bindToPort:]: " @"IPX unsupported, skipping tests"]; break; case ESOCKTNOSUPPORT: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[bindToPort:]: " @"SPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeLine: @"[OFSPXStreamSocket] -[bindToPort:]: " @"IPX not configured, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } of_socket_address_get_ipx_node(&address1, node); network = of_socket_address_get_ipx_network(&address1); port = of_socket_address_get_port(&address1); TEST(@"-[listen]", R([sockServer listen])) TEST(@"-[connectToNode:network:port:]", R([sockClient connectToNode: node network: network port: port])) TEST(@"-[accept]", (sockAccepted = [sockServer accept])) /* Test reassembly (this would not work with OFSPXSocket) */ TEST(@"-[writeBuffer:length:]", R([sockAccepted writeBuffer: "Hello" length: 5])) TEST(@"-[readIntoBuffer:length:]", [sockClient readIntoBuffer: buffer length: 2] == 2 && memcmp(buffer, "He", 2) == 0 && [sockClient readIntoBuffer: buffer length: 3] == 3 && memcmp(buffer, "llo", 3) == 0) TEST(@"-[remoteAddress]", (address2 = sockAccepted.remoteAddress) && R(of_socket_address_get_ipx_node(address2, node2)) && memcmp(node, node2, IPX_NODE_LEN) == 0 && of_socket_address_get_ipx_network(address2) == network) delegate = [[[SPXStreamSocketDelegate alloc] init] autorelease]; sockServer = [OFSPXStreamSocket socket]; delegate->_expectedServerSocket = sockServer; sockServer.delegate = delegate; sockClient = [OFSPXStreamSocket socket]; delegate->_expectedClientSocket = sockClient; sockClient.delegate = delegate; address1 = [sockServer bindToPort: 0]; [sockServer listen]; [sockServer asyncAccept]; of_socket_address_get_ipx_node(&address1, node); memcpy(delegate->_expectedNode, node, IPX_NODE_LEN); delegate->_expectedNetwork = network = of_socket_address_get_ipx_network(&address1); delegate->_expectedPort = port = of_socket_address_get_port(&address1); [sockClient asyncConnectToNode: node network: network port: port]; [[OFRunLoop mainRunLoop] runUntilDate: [OFDate dateWithTimeIntervalSinceNow: 2]]; TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]", delegate->_accepted && delegate->_connected) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSystemInfoTests.m from [fbcca99557] to [fe712afca4].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #include "config.h" #import "TestsAppDelegate.h" | < < > > > | > | > | | | | | | | > | | > | > | > | > | > | > | > | > | > | > | > | > | > | > | | | > | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | * file. */ #include "config.h" #import "TestsAppDelegate.h" @implementation TestsAppDelegate (OFSystemInfoTests) - (void)systemInfoTests { void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_FILES OFString *userConfigPath, *userDataPath; #endif of_stdout.foregroundColor = [OFColor lime]; [of_stdout writeFormat: @"[OFSystemInfo] Page size: %zd\n", [OFSystemInfo pageSize]]; [of_stdout writeFormat: @"[OFSystemInfo] Number of CPUs: %zd\n", [OFSystemInfo numberOfCPUs]]; [of_stdout writeFormat: @"[OFSystemInfo] ObjFW version: %@\n", [OFSystemInfo ObjFWVersion]]; [of_stdout writeFormat: @"[OFSystemInfo] ObjFW version major: %u\n", [OFSystemInfo ObjFWVersionMajor]]; [of_stdout writeFormat: @"[OFSystemInfo] ObjFW version minor: %u\n", [OFSystemInfo ObjFWVersionMinor]]; [of_stdout writeFormat: @"[OFSystemInfo] Operating system name: %@\n", [OFSystemInfo operatingSystemName]]; [of_stdout writeFormat: @"[OFSystemInfo] Operating system version: %@\n", [OFSystemInfo operatingSystemVersion]]; #ifdef OF_HAVE_FILES @try { userConfigPath = [OFSystemInfo userConfigPath]; } @catch (OFNotImplementedException *e) { userConfigPath = @"Not implemented"; } [of_stdout writeFormat: @"[OFSystemInfo] User config path: %@\n", userConfigPath]; @try { userDataPath = [OFSystemInfo userDataPath]; } @catch (OFNotImplementedException *e) { userDataPath = @"Not implemented"; } [of_stdout writeFormat: @"[OFSystemInfo] User data path: %@\n", userDataPath]; #endif [of_stdout writeFormat: @"[OFSystemInfo] CPU vendor: %@\n", [OFSystemInfo CPUVendor]]; [of_stdout writeFormat: @"[OFSystemInfo] CPU model: %@\n", [OFSystemInfo CPUModel]]; #if defined(OF_X86_64) || defined(OF_X86) [of_stdout writeFormat: @"[OFSystemInfo] Supports MMX: %d\n", [OFSystemInfo supportsMMX]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SSE: %d\n", [OFSystemInfo supportsSSE]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SSE2: %d\n", [OFSystemInfo supportsSSE2]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SSE3: %d\n", [OFSystemInfo supportsSSE3]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SSSE3: %d\n", [OFSystemInfo supportsSSSE3]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SSE4.1: %d\n", [OFSystemInfo supportsSSE41]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SSE4.2: %d\n", [OFSystemInfo supportsSSE42]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports AVX: %d\n", [OFSystemInfo supportsAVX]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports AVX2: %d\n", [OFSystemInfo supportsAVX2]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports AES-NI: %d\n", [OFSystemInfo supportsAESNI]]; [of_stdout writeFormat: @"[OFSystemInfo] Supports SHA extensions: %d\n", [OFSystemInfo supportsSHAExtensions]]; #endif #ifdef OF_POWERPC [of_stdout writeFormat: @"[OFSystemInfo] Supports AltiVec: %d\n", [OFSystemInfo supportsAltiVec]]; #endif objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFWindowsRegistryKeyTests.m from [d53759aab6] to [814a5cca52].
︙ | ︙ | |||
25 26 27 28 29 30 31 | - (void)windowsRegistryKeyTests { void *pool = objc_autoreleasePoolPush(); OFData *data = [OFData dataWithItems: "abcdef" count: 6]; OFWindowsRegistryKey *softwareKey, *ObjFWKey; DWORD type; | < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | - (void)windowsRegistryKeyTests { void *pool = objc_autoreleasePoolPush(); OFData *data = [OFData dataWithItems: "abcdef" count: 6]; OFWindowsRegistryKey *softwareKey, *ObjFWKey; DWORD type; TEST(@"+[OFWindowsRegistryKey classesRootKey]", [OFWindowsRegistryKey classesRootKey]) TEST(@"+[OFWindowsRegistryKey currentConfigKey]", [OFWindowsRegistryKey currentConfigKey]) |
︙ | ︙ | |||
60 61 62 63 64 65 66 | TEST(@"-[setData:forValue:type:]", R([ObjFWKey setData: data forValue: @"data" type: REG_BINARY])) TEST(@"-[dataForValue:subkeyPath:flags:type:]", | | < < | | < | < < | | < < < < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | TEST(@"-[setData:forValue:type:]", R([ObjFWKey setData: data forValue: @"data" type: REG_BINARY])) TEST(@"-[dataForValue:subkeyPath:flags:type:]", [[ObjFWKey dataForValue: @"data" type: &type] isEqual: data] && type == REG_BINARY) TEST(@"-[setString:forValue:type:]", R([ObjFWKey setString: @"foobar" forValue: @"string"]) && R([ObjFWKey setString: @"%PATH%;foo" forValue: @"expand" type: REG_EXPAND_SZ])) TEST(@"-[stringForValue:subkeyPath:]", [[ObjFWKey stringForValue: @"string"] isEqual: @"foobar"] && [[ObjFWKey stringForValue: @"expand" type: &type] isEqual: @"%PATH%;foo"] && type == REG_EXPAND_SZ) TEST(@"-[deleteValue:]", R([ObjFWKey deleteValue: @"data"])) TEST(@"-[deleteSubkeyAtPath:]", R([softwareKey deleteSubkeyAtPath: @"ObjFW"])) objc_autoreleasePoolPop(pool); } @end |
Modified tests/TestsAppDelegate.h from [d4258998b2] to [95a43bbf18].
︙ | ︙ | |||
50 51 52 53 54 55 56 | else { \ [self outputFailure: test \ inModule: module]; \ _fails++; \ } \ } #define R(...) (__VA_ARGS__, 1) | < < < < < < < < < < < < < < < < | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | else { \ [self outputFailure: test \ inModule: module]; \ _fails++; \ } \ } #define R(...) (__VA_ARGS__, 1) @class OFString; @interface TestsAppDelegate: OFObject <OFApplicationDelegate> { int _fails; } - (void)outputTesting: (OFString *)test inModule: (OFString *)module; - (void)outputSuccess: (OFString *)test inModule: (OFString *)module; - (void)outputFailure: (OFString *)test inModule: (OFString *)module; @end |
︙ | ︙ | |||
129 130 131 132 133 134 135 136 137 138 139 140 141 142 | @interface TestsAppDelegate (OFHTTPCookieManagerTests) - (void)HTTPCookieManagerTests; @end @interface TestsAppDelegate (OFINIFileTests) - (void)INIFileTests; @end @interface TestsAppDelegate (OFInvocationTests) - (void)invocationTests; @end @interface TestsAppDelegate (OFJSONTests) - (void)JSONTests; | > > > > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | @interface TestsAppDelegate (OFHTTPCookieManagerTests) - (void)HTTPCookieManagerTests; @end @interface TestsAppDelegate (OFINIFileTests) - (void)INIFileTests; @end @interface TestsAppDelegate (OFIPXSocketTests) - (void)IPXSocketTests; @end @interface TestsAppDelegate (OFInvocationTests) - (void)invocationTests; @end @interface TestsAppDelegate (OFJSONTests) - (void)JSONTests; |
︙ | ︙ | |||
186 187 188 189 190 191 192 | - (void)RIPEMD160HashTests; @end @interface TestsAppDelegate (ScryptTests) - (void)scryptTests; @end | < < < < < < < < > > > > > > > > > > > > > > > > > > > > | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | - (void)RIPEMD160HashTests; @end @interface TestsAppDelegate (ScryptTests) - (void)scryptTests; @end @interface TestsAppDelegate (OFSHA1HashTests) - (void)SHA1HashTests; @end @interface TestsAppDelegate (OFSHA224HashTests) - (void)SHA224HashTests; @end @interface TestsAppDelegate (OFSHA256HashTests) - (void)SHA256HashTests; @end @interface TestsAppDelegate (OFSHA384HashTests) - (void)SHA384HashTests; @end @interface TestsAppDelegate (OFSHA512HashTests) - (void)SHA512HashTests; @end @interface TestsAppDelegate (OFSCTPSocketTests) - (void)SCTPSocketTests; @end @interface TestsAppDelegate (OFSPXSocketTests) - (void)SPXSocketTests; @end @interface TestsAppDelegate (OFSPXStreamSocketTests) - (void)SPXStreamSocketTests; @end @interface TestsAppDelegate (OFSerializationTests) - (void)serializationTests; @end @interface TestsAppDelegate (OFSetTests) - (void)setTests; @end @interface TestsAppDelegate (OFSystemInfoTests) - (void)systemInfoTests; @end @interface TestsAppDelegate (OFHMACTests) - (void)HMACTests; |
︙ | ︙ |
Modified tests/TestsAppDelegate.m from [8cfd87b118] to [ab72b7da5d].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #include "config.h" #include <stdlib.h> #import "TestsAppDelegate.h" | < < < < < < | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "config.h" #include <stdlib.h> #import "TestsAppDelegate.h" #ifdef OF_IOS # include <CoreFoundation/CoreFoundation.h> #endif #ifdef OF_PSP # include <pspmoduleinfo.h> # include <pspkernel.h> |
︙ | ︙ | |||
143 144 145 146 147 148 149 | #if defined(OF_WII) || defined(OF_PSP) || defined(OF_NINTENDO_DS) || \ defined(OF_NINTENDO_3DS) @try { return of_application_main(&argc, &argv, [[TestsAppDelegate alloc] init]); } @catch (id e) { | < < > | < | | > | | > | | > | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > | < < | < | < < < | | | > | < < | | < < | > > | | < < < | > | | | | | | | | | | > | | | | | | | | | | | | | | | > | | | | | | | | | | > | | | | | | | | | > > > > | | < < | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | #if defined(OF_WII) || defined(OF_PSP) || defined(OF_NINTENDO_DS) || \ defined(OF_NINTENDO_3DS) @try { return of_application_main(&argc, &argv, [[TestsAppDelegate alloc] init]); } @catch (id e) { OFString *string = [OFString stringWithFormat: @"\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 writeString: string]; [of_stdout writeString: backtrace]; # if defined(OF_WII) [of_stdout reset]; [of_stdout writeString: @"Press home button to exit!"]; for (;;) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) [OFApplication terminateWithStatus: 1]; VIDEO_WaitVSync(); } # elif defined(OF_PSP) sceKernelSleepThreadCB(); # elif defined(OF_NINTENDO_DS) [of_stdout reset]; [of_stdout writeString: @"Press start button to exit!"]; for (;;) { swiWaitForVBlank(); scanKeys(); if (keysDown() & KEY_START) [OFApplication terminateWithStatus: 1]; } # elif defined(OF_NINTENDO_3DS) [of_stdout reset]; [of_stdout writeString: @"Press start button to exit!"]; for (;;) { hidScanInput(); if (hidKeysDown() & KEY_START) [OFApplication terminateWithStatus: 1]; gspWaitForVBlank(); } # else abort(); # endif } #else return of_application_main(&argc, &argv, [[TestsAppDelegate alloc] init]); #endif } @implementation TestsAppDelegate - (void)outputTesting: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { of_stdout.foregroundColor = [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.cursorColumn = 0; of_stdout.foregroundColor = [OFColor lime]; [of_stdout eraseLine]; [of_stdout writeFormat: @"[%@] %@: ok\n", module, test]; } else [of_stdout writeLine: @"ok"]; } - (void)outputFailure: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { of_stdout.cursorColumn = 0; of_stdout.foregroundColor = [OFColor red]; [of_stdout eraseLine]; [of_stdout writeFormat: @"[%@] %@: failed\n", module, test]; #ifdef OF_WII [of_stdout reset]; [of_stdout writeLine: @"Press A to continue!"]; for (;;) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A) return; VIDEO_WaitVSync(); } #endif #ifdef OF_PSP [of_stdout reset]; [of_stdout writeLine: @"Press X to continue!"]; for (;;) { SceCtrlData pad; sceCtrlReadBufferPositive(&pad, 1); if (pad.Buttons & PSP_CTRL_CROSS) { for (;;) { sceCtrlReadBufferPositive(&pad, 1); if (!(pad.Buttons & PSP_CTRL_CROSS)) return; } } } #endif #ifdef OF_NINTENDO_DS [of_stdout reset]; [of_stdout writeString: @"Press A to continue!"]; for (;;) { swiWaitForVBlank(); scanKeys(); if (keysDown() & KEY_A) break; } #endif #ifdef OF_NINTENDO_3DS [of_stdout reset]; [of_stdout writeString: @"Press A to continue!"]; for (;;) { hidScanInput(); if (hidKeysDown() & KEY_A) break; gspWaitForVBlank(); } #endif of_stdout.cursorColumn = 0; [of_stdout reset]; [of_stdout eraseLine]; } else [of_stdout writeLine: @"failed"]; } - (void)applicationDidFinishLaunching { #if defined(OF_IOS) && defined(OF_HAVE_FILES) CFBundleRef mainBundle = CFBundleGetMainBundle(); CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); |
︙ | ︙ | |||
411 412 413 414 415 416 417 418 419 420 421 422 423 424 | #if defined(OF_HAVE_FILES) && defined(HAVE_CODEPAGE_437) [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self socketTests]; [self TCPSocketTests]; [self UDPSocketTests]; [self kernelEventObserverTests]; #endif #ifdef OF_HAVE_THREADS [self threadTests]; #endif [self URLTests]; #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) | > > > > > > > > | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | #if defined(OF_HAVE_FILES) && defined(HAVE_CODEPAGE_437) [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self socketTests]; [self TCPSocketTests]; [self UDPSocketTests]; # ifdef OF_HAVE_SCTP [self SCTPSocketTests]; # endif # ifdef OF_HAVE_IPX [self IPXSocketTests]; [self SPXSocketTests]; [self SPXStreamSocketTests]; # endif [self kernelEventObserverTests]; #endif #ifdef OF_HAVE_THREADS [self threadTests]; #endif [self URLTests]; #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) |
︙ | ︙ | |||
445 446 447 448 449 450 451 452 | #ifdef OF_HAVE_SOCKETS [self DNSResolverTests]; #endif [self systemInfoTests]; [self localeTests]; #if defined(OF_IOS) | > > | < < | | | | < | | | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | #ifdef OF_HAVE_SOCKETS [self DNSResolverTests]; #endif [self systemInfoTests]; [self localeTests]; [of_stdout reset]; #if defined(OF_IOS) [of_stdout writeFormat: @"%d tests failed!", _fails]; [OFApplication terminateWithStatus: _fails]; #elif defined(OF_WII) [of_stdout writeString: @"Press home button to exit!"]; for (;;) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) [OFApplication terminateWithStatus: _fails]; VIDEO_WaitVSync(); } #elif defined(OF_PSP) [of_stdout writeFormat: @"%d tests failed!", _fails]; sceKernelSleepThreadCB(); #elif defined(OF_NINTENDO_DS) [of_stdout writeString: @"Press start button to exit!"]; for (;;) { swiWaitForVBlank(); scanKeys(); if (keysDown() & KEY_START) [OFApplication terminateWithStatus: _fails]; } #elif defined(OF_NINTENDO_3DS) [of_stdout writeString: @"Press start button to exit!"]; for (;;) { hidScanInput(); if (hidKeysDown() & KEY_START) [OFApplication terminateWithStatus: _fails]; gspWaitForVBlank(); } #else [OFApplication terminateWithStatus: _fails]; #endif } @end |
Modified tests/objc_sync/Makefile from [b99d2a03c8] to [050b215f54].
1 2 3 4 5 6 7 8 9 10 11 12 13 | include ../../extra.mk PROG_NOINST = objc_sync${PROG_SUFFIX} SRCS = test.m include ../../buildsys.mk post-all: ${RUN_TESTS} .PHONY: run run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} | | | > | | | | > > > > | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | include ../../extra.mk PROG_NOINST = objc_sync${PROG_SUFFIX} SRCS = test.m include ../../buildsys.mk post-all: ${RUN_TESTS} .PHONY: run run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt.dll libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../../src/libobjfw.so; then \ ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/objfw.dll; then \ ${LN_S} ../../src/objfw.dll objfw.dll; \ fi if test -f ../../src/libobjfw.dylib; then \ ${LN_S} ../../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/libobjfwrt.so; then \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/runtime/objfwrt.dll; then \ ${LN_S} ../../src/runtime/objfwrt.dll objfwrt.dll; \ fi if test -f ../../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f objfw.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.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT CPPFLAGS += -I../../src -I../../src/runtime -I../.. LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS} LD = ${OBJC} |
Modified tests/plugin/TestPlugin.m from [fd38c4331d] to [78de8ec89d].
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "TestPlugin.h" #ifdef OF_OBJFW_RUNTIME # import "runtime/private.h" OF_DESTRUCTOR() { | > > > > > > > > > > > | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #import "TestPlugin.h" #ifdef OF_OBJFW_RUNTIME # import "runtime/private.h" OF_DESTRUCTOR() { Class class = objc_getClass("TestPlugin"); if (class == Nil) /* * musl has broken dlclose(): Instead of calling the destructor * on dlclose(), they call it on exit(). This of course means * that our tests might have already called objc_exit() and the * class is already gone. */ return; objc_unregister_class(class); } #endif @implementation TestPlugin - (int)test: (int)num { return num * 2; |
︙ | ︙ |
Added tests/terminal/Makefile version [58c564f0ae].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | include ../../extra.mk PROG_NOINST = terminal_tests${PROG_SUFFIX} SRCS = TerminalTests.m include ../../buildsys.mk post-all: ${RUN_TESTS} .PHONY: run run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt.dll libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../../src/libobjfw.so; then \ ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/objfw.dll; then \ ${LN_S} ../../src/objfw.dll objfw.dll; \ fi if test -f ../../src/libobjfw.dylib; then \ ${LN_S} ../../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/libobjfwrt.so; then \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/runtime/objfwrt.dll; then \ ${LN_S} ../../src/runtime/objfwrt.dll objfwrt.dll; \ fi if test -f ../../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f objfw.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.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../.. LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS} LD = ${OBJC} |
Added tests/terminal/TerminalTests.m version [3e135bdea5].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFApplication.h" #import "OFArray.h" #import "OFColor.h" #import "OFStdIOStream.h" #import "OFThread.h" @interface TerminalTests: OFObject <OFApplicationDelegate> @end OF_APPLICATION_DELEGATE(TerminalTests) @implementation TerminalTests - (void)applicationDidFinishLaunching { OFArray *colors = [OFArray arrayWithObjects: [OFColor black], [OFColor silver], [OFColor grey], [OFColor white], [OFColor maroon], [OFColor red], [OFColor purple], [OFColor fuchsia], [OFColor green], [OFColor lime], [OFColor olive], [OFColor yellow], [OFColor navy], [OFColor blue], [OFColor teal], [OFColor aqua], nil]; size_t i; OFEnumerator OF_GENERIC(OFColor *) *reverseEnumerator; [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 writeFormat: @"%zx", i++]; } [of_stdout reset]; [of_stdout writeLine: @"R"]; i = 0; for (OFColor *color in colors) { of_stdout.backgroundColor = 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 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]; else of_stdout.foregroundColor = [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 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 writeString: @"Text at (5, 3)"]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(-2, 0)]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(2, 0)]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(0, -2)]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(0, 2)]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(1, 1)]; [OFThread sleepForTimeInterval: 2]; [of_stdout setRelativeCursorPosition: of_point(-1, -1)]; [OFThread sleepForTimeInterval: 2]; of_stdout.cursorColumn = 2; [OFThread sleepForTimeInterval: 2]; [of_stdout reset]; [OFApplication terminate]; } @end |
Modified utils/Makefile from [521b7f89ce] to [82be3d0820].
1 2 3 4 5 6 7 8 9 10 11 12 13 | include ../extra.mk SUBDIRS += ${OFARC} \ ${OFDNS} \ ${OFHASH} \ ${OFHTTP} \ completions include ../buildsys.mk DISTCLEAN = objfw-config install-extra: objfw-config objfw-compile objfw-new | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | include ../extra.mk SUBDIRS += ${OFARC} \ ${OFDNS} \ ${OFHASH} \ ${OFHTTP} \ ${OFSOCK} \ completions include ../buildsys.mk DISTCLEAN = objfw-config install-extra: objfw-config objfw-compile objfw-new |
︙ | ︙ |
Modified utils/completions/fish/Makefile from [00dfed2b56] to [6569e87046].
1 2 3 4 5 6 7 8 9 | DATA = objfw-compile.fish \ objfw-config.fish \ ofarc.fish \ ofhash.fish \ ofhttp.fish include ../../../buildsys.mk PACKAGE_NAME = fish/vendor_completions.d | > | 1 2 3 4 5 6 7 8 9 10 | DATA = objfw-compile.fish \ objfw-config.fish \ ofarc.fish \ ofdns.fish \ ofhash.fish \ ofhttp.fish include ../../../buildsys.mk PACKAGE_NAME = fish/vendor_completions.d |
Added utils/completions/fish/ofdns.fish version [5080d1ffbb].
> > > > > | 1 2 3 4 5 | complete -c ofdns -s c -l class -x -d 'The DNS class to query (defaults to IN)' complete -c ofdns -s h -l help -d 'Show help' complete -c ofdns -s s -l server -x -d 'The server to query' complete -c ofdns -s t -l type -x \ -d 'The record type to query (defaults to ALL, can be repeated)' |
Modified utils/completions/fish/ofhttp.fish from [da383b0d98] to [99fd9b7109].
1 2 3 4 5 6 7 | complete -c ofhttp -s b -l body -r -d 'Specify the file to send as body' complete -c ofhttp -s c -l continue -d 'Continue download of existing file' complete -c ofhttp -s f -l force -d 'Force / overwrite existing file' complete -c ofhttp -s h -l help -d 'Show help' complete -c ofhttp -s H -l header -x -d 'Add a header (e.g. X-Foo:Bar)' complete -c ofhttp -s m -l method -x -d 'Set the method of the HTTP request' complete -c ofhttp -s o -l output -r -d 'Specify output file name' | > | 1 2 3 4 5 6 7 8 | complete -c ofhttp -x complete -c ofhttp -s b -l body -r -d 'Specify the file to send as body' complete -c ofhttp -s c -l continue -d 'Continue download of existing file' complete -c ofhttp -s f -l force -d 'Force / overwrite existing file' complete -c ofhttp -s h -l help -d 'Show help' complete -c ofhttp -s H -l header -x -d 'Add a header (e.g. X-Foo:Bar)' complete -c ofhttp -s m -l method -x -d 'Set the method of the HTTP request' complete -c ofhttp -s o -l output -r -d 'Specify output file name' |
︙ | ︙ |
Modified utils/ofarc/LHAArchive.m from [ac9c3a4448] to [8c23d6ffc7].
︙ | ︙ | |||
117 118 119 120 121 122 123 | @"%" PRIu32, entry.uncompressedSize]; OFString *CRC16 = [OFString stringWithFormat: @"%04" PRIX16, entry.CRC16]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compressed_size", | > | > > > > > > | > > > > > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | @"%" PRIu32, entry.uncompressedSize]; OFString *CRC16 = [OFString stringWithFormat: @"%04" PRIX16, entry.CRC16]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compressed_size", [@"[" @" 'Compressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]" JSONValue], @"size", compressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_uncompressed_size", [@"[" @" 'Uncompressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]" JSONValue], @"size", uncompressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compression_method", @"Compression method: %[method]", @"method", entry.compressionMethod)]; [of_stdout writeString: @"\t"]; |
︙ | ︙ |
Modified utils/ofarc/OFArc.m from [656314f25a] to [f2fa0ce091].
︙ | ︙ | |||
33 34 35 36 37 38 39 | #import "GZIPArchive.h" #import "LHAArchive.h" #import "TarArchive.h" #import "ZIPArchive.h" #import "OFCreateDirectoryFailedException.h" #import "OFInvalidArgumentException.h" | < | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #import "GZIPArchive.h" #import "LHAArchive.h" #import "TarArchive.h" #import "ZIPArchive.h" #import "OFCreateDirectoryFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" #import "OFReadFailedException.h" #import "OFSeekFailedException.h" #import "OFWriteFailedException.h" |
︙ | ︙ | |||
147 148 149 150 151 152 153 | @"Writing archives of type %[type] is not (yet) supported!", @"type", type)]; } @implementation OFArc - (void)applicationDidFinishLaunching { | | < > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | @"Writing archives of type %[type] is not (yet) supported!", @"type", type)]; } @implementation OFArc - (void)applicationDidFinishLaunching { OFString *outputDir, *encodingString, *type; const of_options_parser_option_t options[] = { { 'a', @"append", 0, NULL, NULL }, { 'c', @"create", 0, NULL, NULL }, { 'C', @"directory", 1, NULL, &outputDir }, { 'E', @"encoding", 1, NULL, &encodingString }, { 'f', @"force", 0, NULL, NULL }, { 'h', @"help", 0, NULL, NULL }, { 'l', @"list", 0, NULL, NULL }, { 'n', @"no-clobber", 0, NULL, NULL }, { 'p', @"print", 0, NULL, NULL }, { 'q', @"quiet", 0, NULL, NULL }, { 't', @"type", 1, NULL, &type }, { 'v', @"verbose", 0, NULL, NULL }, { 'x', @"extract", 0, NULL, NULL }, { '\0', nil, 0, NULL, NULL } }; of_unichar_t option, mode = '\0'; of_string_encoding_t encoding = OF_STRING_ENCODING_AUTODETECT; OFOptionsParser *optionsParser; OFArray OF_GENERIC(OFString *) *remainingArguments, *files; id <Archive> archive; #ifdef OF_HAVE_SANDBOX OFSandbox *sandbox = [OFSandbox sandbox]; sandbox.allowsStdIO = true; sandbox.allowsReadingFiles = true; |
︙ | ︙ | |||
289 290 291 292 293 294 295 296 297 298 299 300 301 | @"unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; } } @try { if (encodingString != nil) encoding = of_string_parse_encoding(encodingString); | > | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | @"unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; } } @try { if (encodingString != nil) encoding = of_string_parse_encoding(encodingString); } @catch (OFInvalidArgumentException *e) { [of_stderr writeLine: OF_LOCALIZED( @"invalid_encoding", @"%[prog]: Invalid encoding: %[encoding]", @"prog", [OFApplication programName], @"encoding", encodingString)]; [OFApplication terminateWithStatus: 1]; |
︙ | ︙ | |||
669 670 671 672 673 674 675 | _overwrite = -1; if ([line isEqual: @"n"] || [line isEqual: @"N"]) { if (_outputLevel >= 0) [of_stdout writeLine: OF_LOCALIZED(@"skipping_file", @"Skipping %[file]...", @"file", fileName)]; | > | | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 | _overwrite = -1; if ([line isEqual: @"n"] || [line isEqual: @"N"]) { if (_outputLevel >= 0) [of_stdout writeLine: OF_LOCALIZED(@"skipping_file", @"Skipping %[file]...", @"file", fileName)]; return false; } if (_outputLevel >= 0) [of_stdout writeString: OF_LOCALIZED(@"extracting_file", @"Extracting %[file]...", @"file", fileName)]; |
︙ | ︙ |
Modified utils/ofarc/TarArchive.m from [5bec331bce] to [ce61d629aa].
︙ | ︙ | |||
106 107 108 109 110 111 112 | OFString *UID = [OFString stringWithFormat: @"%u", entry.UID]; OFString *GID = [OFString stringWithFormat: @"%u", entry.GID]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED(@"list_size", | > > > > | > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | OFString *UID = [OFString stringWithFormat: @"%u", entry.UID]; 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)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED(@"list_mode", @"Mode: %[mode]", @"mode", mode)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED(@"list_uid", |
︙ | ︙ |
Modified utils/ofarc/ZIPArchive.m from [2678f9aad0] to [f7e021bab7].
︙ | ︙ | |||
118 119 120 121 122 123 124 | stringWithFormat: @"%08" PRIX32, entry.CRC32]; OFString *modificationDate = [entry.modificationDate localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compressed_size", | > | > > > > > > | > > > > > | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | stringWithFormat: @"%08" PRIX32, entry.CRC32]; OFString *modificationDate = [entry.modificationDate 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], @"size", compressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_uncompressed_size", [@"[" @" 'Uncompressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]" JSONValue], @"size", uncompressedSize)]; [of_stdout writeString: @"\t"]; [of_stdout writeLine: OF_LOCALIZED( @"list_compression_method", @"Compression method: %[method]", @"method", compressionMethod)]; [of_stdout writeString: @"\t"]; |
︙ | ︙ |
Modified utils/ofarc/lang/de.json from [277b513dff] to [d777ea4bdf].
︙ | ︙ | |||
64 65 66 67 68 69 70 | "cannot_list_gz": "Kann Dateien eines .gz-Archivs nicht auflisten!", "cannot_extract_specific_file_from_gz": [ "Kann keine spezifische Datei aus einem .gz-Archiv entpacken!" ], "cannot_print_specific_file_from_gz": [ "Kann keine spezifische Datei aus einem .gz-Archiv ausgeben!" ], | | > > > > > > | > > > > > > | > > > > > > | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | "cannot_list_gz": "Kann Dateien eines .gz-Archivs nicht auflisten!", "cannot_extract_specific_file_from_gz": [ "Kann keine spezifische Datei aus einem .gz-Archiv entpacken!" ], "cannot_print_specific_file_from_gz": [ "Kann keine spezifische Datei aus einem .gz-Archiv ausgeben!" ], "list_size": [ "Größe: ", [ {"size == 1": "1 Byte"}, {"": "%[size] Bytes"} ] ], "list_mode": "Modus: %[mode]", "list_owner": "Besitzer: %[owner]", "list_group": "Gruppe: %[group]", "list_header_level": "Header-Level: %[level]", "list_modification_date": "Änderungsdatum: %[date]", "list_type_normal": "Typ: Normale Datei", "list_type_hardlink": "Typ: Harter Link", "list_type_symlink": "Typ: Symbolischer Link", "list_link_target": "Zieldateiname: %[target]", "list_type_character_device": "Typ: Zeichenorientiertes Gerät", "list_type_block_device": "Typ: Blockorientiertes Gerät", "list_device_major": "Major-Nummer des Geräts: %[major]", "list_device_minor": "Minor-Nummer des Geräts: %[minor]", "list_type_directory": "Typ: Verzeichnis", "list_type_fifo": "Typ: FIFO", "list_type_contiguous_file": "Typ: Zusammenhängende Datei", "list_type_unknown": "Typ: Unbekannt", "list_compressed_size": [ "Komprimierte Größe: ", [ {"size == 1": "1 Byte"}, {"": "%[size] Bytes"} ] ], "list_uncompressed_size": [ "Unkomprimierte Größe: ", [ {"size == 1": "1 Byte"}, {"": "%[size] Bytes"} ] ], "list_compression_method": "Kompressionsmethode: %[method]", "list_date": "Datum: %[date]", "list_osid": "Betriebssystem-Identifikator: %[osid]", "list_extensions": "Erweiterungen: %[extensions]", "list_version_made_by": "Erstellt mit Version: %[version]", "list_min_version_needed": "Mindestens benötigte Version: %[version]", "list_general_purpose_bit_flag": "General Purpose Bit Flag: %[gpbf]", |
︙ | ︙ |
Modified utils/ofdns/Makefile from [3c6086809b] to [c6c2ac1b61].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | include ../../extra.mk PROG = ofdns${PROG_SUFFIX} SRCS = OFDNS.m include ../../buildsys.mk PACKAGE_NAME = ofdns ${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} CPPFLAGS += -I../../src \ -I../../src/runtime \ -I../../src/exceptions \ | > > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | include ../../extra.mk PROG = ofdns${PROG_SUFFIX} SRCS = OFDNS.m DATA = lang/de.json \ lang/languages.json include ../../buildsys.mk PACKAGE_NAME = ofdns ${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} CPPFLAGS += -I../../src \ -I../../src/runtime \ -I../../src/exceptions \ -I../.. \ -DLANGUAGE_DIR=\"${datadir}/ofdns/lang\" LIBS := -L../../src -lobjfw \ -L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS} \ ${LIBS} LD = ${OBJC} LDFLAGS += ${LDFLAGS_RPATH} |
Modified utils/ofdns/OFDNS.m from [e5a880b500] to [7cbfa15818].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | */ #include "config.h" #import "OFApplication.h" #import "OFArray.h" #import "OFDNSResolver.h" #import "OFSandbox.h" #import "OFStdIOStream.h" @interface OFDNS: OFObject <OFApplicationDelegate, OFDNSResolverQueryDelegate> @end OF_APPLICATION_DELEGATE(OFDNS) @implementation OFDNS - (void)resolver: (OFDNSResolver *)resolver didPerformQuery: (OFDNSQuery *)query response: (OFDNSResponse *)response exception: (id)exception { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | | > < | | > > > > > > > > > > > | > | | | | > > > > > > | > > > > > > > > > > > | > > > > > > > > > > > > > > > > | > > > > > > > | > > > > > > > > > > > > | > | > > > > > > | < | < > | | | | < > > > > > | | | > > | | > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | */ #include "config.h" #import "OFApplication.h" #import "OFArray.h" #import "OFDNSResolver.h" #import "OFLocale.h" #import "OFOptionsParser.h" #import "OFSandbox.h" #import "OFStdIOStream.h" @interface OFDNS: OFObject <OFApplicationDelegate, OFDNSResolverQueryDelegate> { size_t _inFlight; int _errors; } @end OF_APPLICATION_DELEGATE(OFDNS) static void help(OFStream *stream, bool full, int status) { [of_stderr writeLine: OF_LOCALIZED(@"usage", @"Usage: %[prog] -[chst] domain1 [domain2 ...]", @"prog", [OFApplication programName])]; if (full) { [stream writeString: @"\n"]; [stream writeLine: OF_LOCALIZED(@"full_usage", @"Options:\n " @"-c --class " @" The DNS class to query (defaults to IN)\n " @"-h --help " @" Show this help\n " @"-s --server" @" The server to query\n " @"-t --type " @" The record type to query (defaults to ALL, can be " @"repeated)")]; } [OFApplication terminateWithStatus: status]; } @implementation OFDNS - (void)resolver: (OFDNSResolver *)resolver didPerformQuery: (OFDNSQuery *)query response: (OFDNSResponse *)response exception: (id)exception { _inFlight--; if (exception == nil) [of_stdout writeFormat: @"%@\n", response]; else { [of_stderr writeLine: OF_LOCALIZED( @"failed_to_resolve", @"Failed to resolve: %[exception]", @"exception", exception)]; _errors++; } if (_inFlight == 0) [OFApplication terminateWithStatus: _errors]; } - (void)applicationDidFinishLaunching { OFString *DNSClassString, *server; const of_options_parser_option_t options[] = { { 'c', @"class", 1, NULL, &DNSClassString }, { 'h', @"help", 0, NULL, NULL }, { 's', @"server", 1, NULL, &server }, { 't', @"type", 1, NULL, NULL }, { '\0', nil, 0, NULL, NULL } }; OFMutableArray OF_GENERIC(OFString *) *recordTypes; OFOptionsParser *optionsParser; of_unichar_t option; OFArray OF_GENERIC(OFString *) *remainingArguments; OFDNSResolver *resolver; of_dns_class_t DNSClass; #ifdef OF_HAVE_FILES # ifndef OF_AMIGAOS [OFLocale addLanguageDirectory: @LANGUAGE_DIR]; # else [OFLocale addLanguageDirectory: @"PROGDIR:/share/ofdns/lang"]; # endif #endif #ifdef OF_HAVE_SANDBOX OFSandbox *sandbox = [[OFSandbox alloc] init]; @try { sandbox.allowsStdIO = true; sandbox.allowsDNS = true; [OFApplication activateSandbox: sandbox]; } @finally { [sandbox release]; } #endif recordTypes = [OFMutableArray array]; optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 't': [recordTypes addObject: optionsParser.argument]; break; case 'h': help(of_stdout, true, 0); break; case ':': if (optionsParser.lastLongOption != nil) [of_stderr writeLine: OF_LOCALIZED( @"long_option_required_argument", @"%[prog]: Option --%[opt] requires an " @"argument", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%C", optionsParser.lastOption]; [of_stderr writeLine: OF_LOCALIZED( @"option_requires_argument", @"%[prog]: Option -%[opt] requires an " @"argument", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; case '?': if (optionsParser.lastLongOption != nil) [of_stderr writeLine: OF_LOCALIZED( @"unknown_long_option", @"%[prog]: Unknown option: --%[opt]", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%C", optionsParser.lastOption]; [of_stderr writeLine: OF_LOCALIZED( @"Unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; } } remainingArguments = optionsParser.remainingArguments; if (remainingArguments.count < 1) help(of_stderr, false, 1); resolver = [OFDNSResolver resolver]; DNSClass = (DNSClassString != nil ? of_dns_class_parse(DNSClassString) : OF_DNS_CLASS_IN); if (recordTypes.count == 0) [recordTypes addObject: @"ALL"]; if (server != nil) { resolver.configReloadInterval = 0; resolver.nameServers = [OFArray arrayWithObject: server]; } for (OFString *domainName in remainingArguments) { for (OFString *recordTypeString in recordTypes) { of_dns_record_type_t recordType = of_dns_record_type_parse(recordTypeString); OFDNSQuery *query = [OFDNSQuery queryWithDomainName: domainName DNSClass: DNSClass recordType: recordType]; _inFlight++; [resolver asyncPerformQuery: query delegate: self]; } } } @end |
Added utils/ofdns/lang/de.json version [a2dd6e542b].
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | { "usage": "Benutzung: %[prog] -[chst] domain1 [domain2 ...]", "full_usage": [ "Optionen:\n", " -c --class Die anzufragende DNS-Klasse (standardmäßig IN)\n", " -h --help Diese Hilfe anzeigen\n", " -s --server Der abzufragende Server\n", " -t --type Der anzufragende Record-Typ (standardmäßig ALL,\n", " kann wiederholt werden)" ], "long_option_requires_argument": [ "%[prog]: Option --%[opt] benötigt ein Argument" ], "option_requires_argument": "%[prog]: Option -%[opt] benötigt ein Argument", "unknown_long_option": "%[prog]: Unbekannte Option: --%[opt]", "unknown_option": "%[prog]: Unbekannte Option: -%[opt]", "failed_to_resolve": "Auflösen fehlgeschlagen: %[exception]" } |
Added utils/ofdns/lang/languages.json version [1722bb6119].
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | { "de": { "": "de" }, "deutsch": { "": "de" }, "german": { "": "de" } } |
Modified utils/ofhttp/OFHTTP.m from [fb786804a8] to [da5c2f66e5].
︙ | ︙ | |||
33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #import "OFSystemInfo.h" #import "OFTCPSocket.h" #import "OFTLSSocket.h" #import "OFURL.h" #import "OFConnectionFailedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFResolveHostFailedException.h" #import "OFRetrieveItemAttributesFailedException.h" | > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #import "OFSystemInfo.h" #import "OFTCPSocket.h" #import "OFTLSSocket.h" #import "OFURL.h" #import "OFConnectionFailedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFResolveHostFailedException.h" #import "OFRetrieveItemAttributesFailedException.h" |
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 | if (full) { [stream writeString: @"\n"]; [stream writeLine: OF_LOCALIZED(@"full_usage", @"Options:\n " @"-b --body " @" Specify the file to send as body\n " @"-c --continue " @" Continue download of existing file\n " @"-f --force " @" Force / overwrite existing file\n " @"-h --help " @" Show this help\n " @"-H --header " | > > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | if (full) { [stream writeString: @"\n"]; [stream writeLine: OF_LOCALIZED(@"full_usage", @"Options:\n " @"-b --body " @" Specify the file to send as body\n " @" " @" (- for standard input)\n " @"-c --continue " @" Continue download of existing file\n " @"-f --force " @" Force / overwrite existing file\n " @"-h --help " @" Show this help\n " @"-H --header " |
︙ | ︙ | |||
315 316 317 318 319 320 321 | [_clientHeaders setObject: value forKey: name]; } - (void)setBody: (OFString *)path { | | > > > > > | | > | | > > > | | > > > > > > > | | | < < < < < < < < < < | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | [_clientHeaders setObject: value forKey: name]; } - (void)setBody: (OFString *)path { OFString *contentLength = nil; [_body release]; _body = nil; if ([path isEqual: @"-"]) _body = [of_stdin copy]; else { _body = [[OFFile alloc] initWithPath: path mode: @"r"]; @try { uintmax_t fileSize = [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; contentLength = [OFString stringWithFormat: @"%ju", fileSize]; [_clientHeaders setObject: contentLength forKey: @"Content-Length"]; } @catch (OFRetrieveItemAttributesFailedException *e) { } } if (contentLength == nil) [_clientHeaders setObject: @"chunked" forKey: @"Transfer-Encoding"]; } - (void)setMethod: (OFString *)method { void *pool = objc_autoreleasePoolPush(); method = method.uppercaseString; @try { _method = of_http_request_method_from_string(method); } @catch (OFInvalidArgumentException *e) { [of_stderr writeLine: OF_LOCALIZED(@"invalid_input_method", @"%[prog]: Invalid request method %[method]!", @"prog", [OFApplication programName], @"method", method)]; [OFApplication terminateWithStatus: 1]; } |
︙ | ︙ | |||
545 546 547 548 549 550 551 | @"%[prog]: Cannot use -o / --output when more than one URL " @"has been specified!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } if (_insecure) | | | | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | @"%[prog]: Cannot use -o / --output when more than one URL " @"has been specified!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } if (_insecure) _HTTPClient.allowsInsecureRedirects = true; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)sock request: (OFHTTPRequest *)request { if (_insecure && [sock respondsToSelector: @selector(setVerifiesCertificates:)]) ((id <OFTLSSocket>)sock).verifiesCertificates = false; } - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)body request: (OFHTTPRequest *)request { /* TODO: Do asynchronously and print status */ |
︙ | ︙ | |||
678 679 680 681 682 683 684 685 | @"%[prog]: Failed to download <%[url]>!\n" @" %[error]: %[exception]", @"prog", [OFApplication programName], @"url", request.URL.string, @"error", error, @"exception", e)]; } else if ([e isKindOfClass: [OFHTTPRequestFailedException class]]) { [of_stderr writeLine: OF_LOCALIZED(@"download_failed", | > > > | > | > | 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | @"%[prog]: Failed to download <%[url]>!\n" @" %[error]: %[exception]", @"prog", [OFApplication programName], @"url", request.URL.string, @"error", error, @"exception", e)]; } else if ([e isKindOfClass: [OFHTTPRequestFailedException class]]) { short statusCode = [[e response] statusCode]; OFString *codeString = [OFString stringWithFormat: @"%d %@", statusCode, of_http_status_code_to_string(statusCode)]; [of_stderr writeLine: OF_LOCALIZED(@"download_failed", @"%[prog]: Failed to download <%[url]>!\n" @" HTTP status code: %[code]", @"prog", [OFApplication programName], @"url", request.URL.string, @"code", codeString)]; } else @throw e; _errorCode = 1; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } |
︙ | ︙ | |||
709 710 711 712 713 714 715 | if (!_quiet) [of_stdout writeString: @"\n Error!\n"]; URL = [_URLs objectAtIndex: _URLIndex - 1]; [of_stderr writeLine: OF_LOCALIZED( @"download_failed_exception", | | > | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 | if (!_quiet) [of_stdout writeString: @"\n Error!\n"]; URL = [_URLs objectAtIndex: _URLIndex - 1]; [of_stderr writeLine: OF_LOCALIZED( @"download_failed_exception", @"%[prog]: Failed to download <%[url]>!\n" @" %[exception]", @"prog", [OFApplication programName], @"url", URL, @"exception", exception)]; _errorCode = 1; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; |
︙ | ︙ | |||
793 794 795 796 797 798 799 | lengthString = OF_LOCALIZED(@"size_kib", @"%[num] KiB", @"num", lengthString); } else { lengthString = [OFString stringWithFormat: @"%jd", _resumedFrom + _length]; lengthString = OF_LOCALIZED(@"size_bytes", | > > > | > > | 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 | lengthString = OF_LOCALIZED(@"size_kib", @"%[num] KiB", @"num", lengthString); } else { lengthString = [OFString stringWithFormat: @"%jd", _resumedFrom + _length]; lengthString = OF_LOCALIZED(@"size_bytes", [@"[" @" [" @" {'num == 1': '1 byte'}," @" {'': '%[num] bytes'}" @" ]" @"]" JSONValue], @"num", lengthString); } } else lengthString = OF_LOCALIZED(@"size_unknown", @"unknown"); if (_verbose) { |
︙ | ︙ | |||
843 844 845 846 847 848 849 850 851 852 853 854 855 856 | } } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { if (_detectFileNameRequest) { _currentFileName = [fileNameFromContentDisposition( [response.headers objectForKey: @"Content-Disposition"]) copy]; _detectedFileName = true; /* Handle this URL on the next -[downloadNextURL] call */ | > > > | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 | } } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { if (_method == OF_HTTP_REQUEST_METHOD_HEAD) goto next; if (_detectFileNameRequest) { _currentFileName = [fileNameFromContentDisposition( [response.headers objectForKey: @"Content-Disposition"]) copy]; _detectedFileName = true; /* Handle this URL on the next -[downloadNextURL] call */ |
︙ | ︙ |
Modified utils/ofhttp/ProgressBar.m from [cdabadff8c] to [813833df71].
︙ | ︙ | |||
200 201 202 203 204 205 206 | [of_stdout writeString: OF_LOCALIZED(@"progress_kib", @"%[num] KiB", @"num", num)]; } else { OFString *num = [OFString stringWithFormat: @"%jd", _resumedFrom + _received]; [of_stdout writeString: OF_LOCALIZED(@"progress_bytes", | > > > | > > | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | [of_stdout writeString: OF_LOCALIZED(@"progress_kib", @"%[num] KiB", @"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", num)]; } [of_stdout writeString: @" "]; if (_stopped) _BPS = (float)_received / |
︙ | ︙ |
Modified utils/ofhttp/lang/de.json from [9e4f95f1d1] to [ef4298a3ca].
1 2 3 4 5 6 7 8 9 10 11 12 | { "usage": "Benutzung: %[prog] -[cehHmoOPqv] url1 [url2 ...]", "full_usage": [ "Optionen:\n", " -b --body Angegebene Datei als Body übergeben\n", " -c --continue Download von existierender Datei ", "fortsetzen\n", " -f --force Existierende Datei überschreiben\n", " -h --help Diese Hilfe anzeigen\n", " -H --header Einen Header (z.B. X-Foo:Bar) hinzufügen\n", " -m --method HTTP Request-Methode setzen\n", " -o --output Ausgabe-Dateiname angeben\n", | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | { "usage": "Benutzung: %[prog] -[cehHmoOPqv] url1 [url2 ...]", "full_usage": [ "Optionen:\n", " -b --body Angegebene Datei als Body übergeben\n", " (- für Standard-Eingabe)\n", " -c --continue Download von existierender Datei ", "fortsetzen\n", " -f --force Existierende Datei überschreiben\n", " -h --help Diese Hilfe anzeigen\n", " -H --header Einen Header (z.B. X-Foo:Bar) hinzufügen\n", " -m --method HTTP Request-Methode setzen\n", " -o --output Ausgabe-Dateiname angeben\n", |
︙ | ︙ | |||
59 60 61 62 63 64 65 | "download_failed_read_or_write_failed_any": "Lesen oder Schreiben", "download_failed_read_or_write_failed_read": "Lesen", "download_failed_read_or_write_failed_write": "Schreiben", "download_failed_read_or_write_failed": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " %[error]: %[exception]" ], | > | > > | > | > > > > > | > > > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | "download_failed_read_or_write_failed_any": "Lesen oder Schreiben", "download_failed_read_or_write_failed_read": "Lesen", "download_failed_read_or_write_failed_write": "Schreiben", "download_failed_read_or_write_failed": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " %[error]: %[exception]" ], "download_failed": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " HTTP Status-Code: %[code]" ], "download_failed_exception": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " %[exception]" ], "download_done": "Fertig!", "invalid_url": "%[prog]: Ungültige URL: <%[url]>!", "invalid_scheme": "%[prog]: Ungültiges Schema: <%[url]>!", "type_unknown": "unbekannt", "size_gib": "%[num] GiB", "size_mib": "%[num] MiB", "size_kib": "%[num] KiB", "size_bytes": [ [ {"num == 1": "1 Byte"}, {"": "%[num] Bytes"} ] ], "size_unknown": "unbekannt", "info_name_unaligned": "Name: %[name]", "info_name": "Name: %[name]", "info_type": "Typ: %[type]", "info_size": "Größe: %[size]", "output_already_exists": "%[prog]: Datei %[filename] existiert bereits!", "failed_to_open_output": [ "%[prog]: Kann Datei %[filename] nicht öffnen: %[exception]" ], "eta_days": "%[num] t ", "progress_bytes": [ [ {"num == 1": "1 Byte "}, {"": "%[num] Bytes"} ] ] } |
Added utils/ofsock/Makefile version [0438ba0691].
> > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | include ../../extra.mk PROG = ofsock${PROG_SUFFIX} SRCS = OFSock.m include ../../buildsys.mk PACKAGE_NAME = ofsock ${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} CPPFLAGS += -I../../src \ -I../../src/runtime \ -I../../src/exceptions \ -I../.. LIBS := -L../../src -lobjfw \ -L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS} \ ${LIBS} LD = ${OBJC} LDFLAGS += ${LDFLAGS_RPATH} |
Added utils/ofsock/OFSock.m version [0c75e9be8d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 "OFApplication.h" #import "OFArray.h" #import "OFNumber.h" #import "OFPair.h" #import "OFStdIOStream.h" #import "OFStream.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFURL.h" #define BUFFER_LEN 4096 @interface OFSock: OFObject <OFApplicationDelegate, OFStreamDelegate> { char _buffer[BUFFER_LEN]; OFMutableArray OF_GENERIC(OFPair OF_GENERIC(OFStream *, OFStream *) *) *_streams; int _errors; } @end OF_APPLICATION_DELEGATE(OFSock) static OFPair OF_GENERIC(OFStream *, OFStream *) * streamFromString(OFString *string) { OFURL *URL; OFString *scheme; if ([string isEqual: @"-"]) return [OFPair pairWithFirstObject: of_stdin secondObject: of_stdout]; URL = [OFURL URLWithString: string]; scheme = URL.scheme; if ([scheme isEqual: @"tcp"]) { OFTCPSocket *sock = [OFTCPSocket socket]; if (URL.port == nil) { [of_stderr writeLine: @"Need a port!"]; [OFApplication terminateWithStatus: 1]; } [sock connectToHost: URL.host port: URL.port.uInt16Value]; return [OFPair pairWithFirstObject: sock secondObject: sock]; } [of_stderr writeFormat: @"Invalid protocol: %@\n", scheme]; [OFApplication terminateWithStatus: 1]; abort(); } @implementation OFSock - (void)applicationDidFinishLaunching { OFArray OF_GENERIC(OFString *) *arguments = [OFApplication arguments]; if (arguments.count < 1) { [of_stderr writeLine: @"Need at least one argument!"]; [OFApplication terminateWithStatus: 1]; } _streams = [[OFMutableArray alloc] init]; for (OFString *argument in arguments) { OFPair *pair = streamFromString(argument); [pair.firstObject setDelegate: self]; [_streams addObject: pair]; } if (arguments.count == 1) { of_stdin.delegate = self; [_streams addObject: [OFPair pairWithFirstObject: of_stdin secondObject: of_stdout]]; } for (OFPair *pair in _streams) [pair.firstObject asyncReadIntoBuffer: _buffer length: BUFFER_LEN]; } - (void)removeDeadStream: (OFStream *)stream { size_t count = _streams.count; for (size_t i = 0; i < count; i++) { if ([[_streams objectAtIndex: i] firstObject] == stream) { [_streams removeObjectAtIndex: i]; break; } } if (_streams.count < 2) [OFApplication terminateWithStatus: _errors]; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { if (exception != nil) { [of_stderr writeFormat: @"Exception on stream %@: %@\n", stream, exception]; _errors++; [self removeDeadStream: stream]; return false; } if (stream.atEndOfStream) { [self removeDeadStream: stream]; return false; } for (OFPair *pair in _streams) { if (pair.firstObject == stream) continue; [pair.secondObject writeBuffer: buffer length: length]; } return true; } @end |