Comment: | Merge trunk into branch "asn1" |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | asn1 |
Files: | files | file ages | folders |
SHA3-256: |
d8ef56254dc71c16702a6288918f4376 |
User & Date: | js on 2022-11-07 00:20:31 |
Other Links: | branch diff | manifest | tags |
2024-01-11
| ||
20:12 | Merge trunk into branch "asn1" check-in: 4320b1bf7d user: js tags: asn1 | |
2022-11-07
| ||
00:20 | Merge trunk into branch "asn1" check-in: d8ef56254d user: js tags: asn1 | |
00:17 | Merge trunk into branch "asn1" check-in: b37858358e user: js tags: asn1 | |
2022-11-06
| ||
21:37 | Fix OFDDPSocket on NetBSD check-in: 4d97d89c32 user: js tags: trunk | |
Deleted .cirrus.yml version [6338675a88].
|
| < < < < < < < < < < < < < < < < < < < < < < |
Modified .fossil-settings/clean-glob from [c4150a9711] to [06b87ad48d].
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 | tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds tests/tests.nro tests/tests.rpx utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp | > | 46 47 48 49 50 51 52 53 54 55 56 57 | tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds tests/tests.nro tests/tests.rpx utils/objfw-config utils/objfw-new/objfw-new utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp |
Modified .fossil-settings/ignore-glob from [ed0ba1aa38] to [23cb69850b].
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 | tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds tests/tests.nro tests/tests.rpx utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp | > | 51 52 53 54 55 56 57 58 59 60 61 62 | tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds tests/tests.nro tests/tests.rpx utils/objfw-config utils/objfw-new/objfw-new utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp |
Modified .github/workflows/amiga-gcc.yml from [16471286d2] to [d938c3ac40].
1 2 3 4 5 6 7 8 9 10 11 | name: amiga-gcc on: [push, pull_request] jobs: build: runs-on: ubuntu-latest strategy: matrix: configure_flags: - - --disable-amiga-lib steps: | > < < < < < < < | < < < < < | | < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | name: amiga-gcc on: [push, pull_request] jobs: build: runs-on: ubuntu-latest container: amigadev/crosstools:m68k-amigaos strategy: matrix: configure_flags: - - --disable-amiga-lib steps: - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: ./configure --host=m68k-amigaos ${{ matrix.configure_flags }} - name: make run: make -j$(nproc) - name: make install run: make install |
Deleted .github/workflows/macos-10.15.yml version [0b4e6d02a3].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added .github/workflows/macos-12.yml version [a15421158f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | name: macos-12 on: [push, pull_request] jobs: tests: runs-on: macos-12 strategy: matrix: configure_flags: - - --disable-threads - --disable-threads --disable-sockets - --disable-threads --disable-files - --disable-threads --disable-sockets --disable-files - --disable-sockets - --disable-sockets --disable-files - --disable-files - --disable-shared steps: - name: Install dependencies run: brew install autoconf automake - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: ./configure ${{ matrix.configure_flags }} - name: make run: make -j$(sysctl -n hw.logicalcpu) - name: make check run: make check - name: make install run: sudo make install |
Modified .github/workflows/morphos.yml from [0f27c2ab37] to [c3d30801ba].
1 2 3 4 5 6 7 8 9 10 11 | name: morphos on: [push, pull_request] jobs: build: runs-on: ubuntu-latest strategy: matrix: configure_flags: - - --disable-amiga-lib steps: | > < < < < < < < | < < < < < | | < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | name: morphos on: [push, pull_request] jobs: build: runs-on: ubuntu-latest container: amigadev/crosstools:ppc-morphos strategy: matrix: configure_flags: - - --disable-amiga-lib steps: - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: ./configure --host=ppc-morphos ${{ matrix.configure_flags }} - name: make run: make -j$(nproc) - name: make install run: make install |
Modified .github/workflows/nintendo-3ds.yml from [67061ee611] to [b6f005f187].
︙ | ︙ | |||
28 29 30 31 32 33 34 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ | | | 28 29 30 31 32 33 34 35 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c "cd /objfw && make install" |
Modified .github/workflows/nintendo-ds.yml from [3d41e0f5f7] to [1d6308a4b1].
︙ | ︙ | |||
28 29 30 31 32 33 34 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ | | | 28 29 30 31 32 33 34 35 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c "cd /objfw && make install" |
Modified .github/workflows/nintendo-switch.yml from [2a5a4851c5] to [9d8878050b].
︙ | ︙ | |||
28 29 30 31 32 33 34 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkita64 \ | | | 28 29 30 31 32 33 34 35 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkita64 \ sh -c "cd /objfw && make install" |
Renamed and modified .github/workflows/ubuntu-18.04-32bit.yml [96c9a8ae41] to .github/workflows/ubuntu-latest-32bit.yml [3cbf56442c].
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 | name: ubuntu-latest, 32 bit on: [push, pull_request] jobs: tests: runs-on: ubuntu-latest strategy: matrix: configure_flags: - --without-tls - --without-tls --enable-seluid24 - --without-tls --disable-compiler-tls - --without-tls --disable-threads |
︙ | ︙ |
Renamed and modified .github/workflows/ubuntu-18.04-gcc-32bit.yml [0e720701c6] to .github/workflows/ubuntu-latest-gcc-32bit.yml [b827a9a41f].
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 | name: ubuntu-latest, GCC, 32 bit on: [push, pull_request] jobs: tests: runs-on: ubuntu-latest strategy: matrix: configure_flags: - --without-tls - --without-tls --enable-seluid24 - --without-tls --disable-compiler-tls - --without-tls --disable-threads |
︙ | ︙ |
Renamed and modified .github/workflows/ubuntu-18.04-gcc.yml [9e75cc2f04] to .github/workflows/ubuntu-latest-gcc.yml [4509107d9f].
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 | name: ubuntu-latest, GCC on: [push, pull_request] jobs: tests: runs-on: ubuntu-latest strategy: matrix: configure_flags: - - --enable-seluid24 - --disable-compiler-tls - --disable-threads |
︙ | ︙ |
Renamed and modified .github/workflows/ubuntu-18.04.yml [d0186b3566] to .github/workflows/ubuntu-latest.yml [36a38ec742].
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 | name: ubuntu-latest on: [push, pull_request] jobs: tests: runs-on: ubuntu-latest strategy: matrix: configure_flags: - - --enable-seluid24 - --disable-compiler-tls - --disable-threads |
︙ | ︙ |
Modified .github/workflows/wii-u.yml from [b25255900b] to [7d250df7d0].
︙ | ︙ | |||
28 29 30 31 32 33 34 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitppc \ | | | 28 29 30 31 32 33 34 35 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitppc \ sh -c "cd /objfw && make install" |
Modified .github/workflows/wii.yml from [39c842705b] to [59cebc18ff].
︙ | ︙ | |||
28 29 30 31 32 33 34 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitppc \ | | | 28 29 30 31 32 33 34 35 | - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitppc \ sh -c "cd /objfw && make install" |
Modified .gitignore from [42e9f25720] to [726b780402].
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 | tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds tests/tests.nro tests/tests.rpx utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp | > | 51 52 53 54 55 56 57 58 59 60 61 62 | tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds tests/tests.nro tests/tests.rpx utils/objfw-config utils/objfw-new/objfw-new utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp |
Modified Doxyfile from [f4ff92fbc3] to [6b8aa42255].
1 2 3 4 5 6 7 8 9 10 11 | PROJECT_NAME = "ObjFW" OUTPUT_DIRECTORY = docs/ INPUT = src src/exceptions src/runtime FILE_PATTERNS = *.h *.m HTML_OUTPUT = . HAVE_DOT = NO GENERATE_LATEX = NO HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_MEMBERS = YES TYPEDEF_HIDES_STRUCT = YES PREDEFINED = __OBJC__ \ | | | | | | | | | | | | | | | | | 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 | PROJECT_NAME = "ObjFW" OUTPUT_DIRECTORY = docs/ INPUT = src src/exceptions src/runtime FILE_PATTERNS = *.h *.m HTML_OUTPUT = . HAVE_DOT = NO GENERATE_LATEX = NO HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_MEMBERS = YES TYPEDEF_HIDES_STRUCT = YES PREDEFINED = __OBJC__ \ _Nonnull= \ _Nullable= \ DOXYGEN \ OF_BOXABLE= \ OF_CONSUMED= \ OF_DESIGNATED_INITIALIZER= \ OF_GENERIC(...)= \ OF_HAVE_BLOCKS \ OF_HAVE_FILES \ OF_HAVE_SANDBOX \ OF_HAVE_SOCKETS \ OF_HAVE_THREADS \ OF_KINDOF(...)= \ OF_NO_RETURN= \ OF_NO_RETURN_FUNC= \ OF_NULLABLE_PROPERTY(...)= \ OF_NULL_RESETTABLE_PROPERTY(...)= \ OF_REQUIRES_SUPER= \ OF_RETURNS_INNER_POINTER= \ OF_RETURNS_NOT_RETAINED= \ OF_RETURNS_RETAINED= \ OF_ROOT_CLASS= \ OF_SENTINEL= \ OF_WARN_UNUSED_RESULT= \ OF_WEAK_UNAVAILABLE= \ SIGHUP \ SIGUSR1 \ SIGUSR2 MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES IGNORE_PREFIX = OF of_ |
Modified Makefile from [63e28abf9d] to [4341fed160].
︙ | ︙ | |||
24 25 26 27 28 29 30 | doxygen >/dev/null release: docs echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz fossil tarball --name objfw-${PACKAGE_VERSION} current - \ | | | < | | 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 | doxygen >/dev/null release: docs echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz fossil tarball --name objfw-${PACKAGE_VERSION} current - \ --exclude '.fossil*,.git*' | ofarc -ttgz -xq - cp configure config.h.in objfw-${PACKAGE_VERSION}/ ofarc -cq objfw-${PACKAGE_VERSION}.tar objfw-${PACKAGE_VERSION} 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 \ objfw-docs-${PACKAGE_VERSION} 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 README.md from [939967b8be] to [711c05e9ce].
︙ | ︙ | |||
225 226 227 228 229 230 231 | The first thing to install is [MSYS2](https://www.msys2.org) to provide a basic UNIX-like environment for Windows. Unfortunately, the binaries are not signed, so make sure you download it via HTTPS. However, packages you download and install via MSYS2 are cryptographically signed. <h3 id="setting-up-msys2">Setting up MSYS2</h3> | | | | < | < < < < < > > > > > > > > > > > > > > > > | 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 | The first thing to install is [MSYS2](https://www.msys2.org) to provide a basic UNIX-like environment for Windows. Unfortunately, the binaries are not signed, so make sure you download it via HTTPS. However, packages you download and install via MSYS2 are cryptographically signed. <h3 id="setting-up-msys2">Setting up MSYS2</h3> MSYS2 currently supports 7 different [environments](https://www.msys2.org/docs/environments/). All of them except for the one called just "MSYS" are supported, but which packages you need to install depends on the environment(s) you want to use. If you only want to target Windows 10 and newer, the CLANG64 and CLANG32 environments are the recommended ones. For CLANG64, use: $ pacman -Syu mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-fossil For CLANG32, use: $ pacman -Syu mingw-w64-clang-i686-clang mingw-w64-clang-i686-fossil For CLANGARM64, use (you need to use Fossil via another environment): $ pacman -Syu mingw-w64-clang-aarch64-clang For MINGW64, use: $ pacman -Syu mingw-w64-x86_64-clang mingw-w64-x86_64-fossil For MINGW32, use: $ pacman -Syu mingw-w64-i686-clang mingw-w64-i686-fossil For UCRT64, use: $ pacman -Syu mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-fossil When using `pacman` to install the packages, `pacman` might tell you to close the window. If it does so, close the window, restart MSYS2 and execute the `pacman` command again. There is nothing wrong with installing multiple environments, as MSYS2 has created shortcuts for each of them in your start menu. Just make sure to use the correct shortcut for the environment you want to use. |
︙ | ︙ | |||
307 308 309 310 311 312 313 | $ ./configure --host=m68k-amigaos <h1 id="first-app">Writing your first application with ObjFW</h1> To create your first, empty application, you can use `objfw-new`: | | | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | $ ./configure --host=m68k-amigaos <h1 id="first-app">Writing your first application with ObjFW</h1> To create your first, empty application, you can use `objfw-new`: $ objfw-new --app MyFirstApp This creates a file `MyFirstApp.m`. The `-[applicationDidFinishLaunching]` method is called as soon as ObjFW finished all initialization. Use this as the entry point to your own code. For example, you could add the following line there to create a "Hello World": [OFStdOut writeLine: @"Hello World!"]; |
︙ | ︙ |
Modified build-aux/m4/buildsys.m4 from [824bccf73b] to [0e90ccf38e].
︙ | ︙ | |||
205 206 207 208 209 210 211 | *-*-mingw* | *-*-cygwin*) AC_MSG_RESULT(MinGW / Cygwin) LIB_CFLAGS='' LIB_LDFLAGS='-shared -Wl,--export-all-symbols' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='' LIB_SUFFIX='${LIB_MAJOR}.dll' | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | *-*-mingw* | *-*-cygwin*) AC_MSG_RESULT(MinGW / Cygwin) LIB_CFLAGS='' LIB_LDFLAGS='-shared -Wl,--export-all-symbols' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='' LIB_SUFFIX='${LIB_MAJOR}.dll' LINK_LIB='&& rm -f lib$${out%${LIB_SUFFIX}}.dll.a && ${LN_S} $$out lib$${out%${LIB_SUFFIX}}.dll.a' PLUGIN_CFLAGS='' PLUGIN_LDFLAGS='-shared -Wl,--export-all-symbols' 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%${LIB_SUFFIX}}.dll.a ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.dll.a' UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.dll.a' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' |
︙ | ︙ |
Modified buildsys.mk.in from [a085f99653] to [2dfee6e012].
︙ | ︙ | |||
77 78 79 80 81 82 83 | MKDIR_P = mkdir -p INSTALL = @INSTALL@ SHELL = @SHELL@ MSGFMT = @MSGFMT@ JAVAC = @JAVAC@ JAVACFLAGS = @JAVACFLAGS@ JAR = @JAR@ | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | MKDIR_P = mkdir -p INSTALL = @INSTALL@ SHELL = @SHELL@ MSGFMT = @MSGFMT@ JAVAC = @JAVAC@ JAVACFLAGS = @JAVACFLAGS@ JAR = @JAR@ RC = @RC@ BUILD_AND_HOST_ARE_DARWIN = @BUILD_AND_HOST_ARE_DARWIN@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ amigalibdir ?= ${prefix}/libs plugindir ?= ${libdir}/${PACKAGE_NAME} |
︙ | ︙ | |||
575 576 577 578 579 580 581 | ${COMPILE_FAILED}; \ fi .rc.o .rc.lib.o .rc.plugin.o: ${COMPILE_STATUS} in="$<"; \ out="$@"; \ | | | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | ${COMPILE_FAILED}; \ fi .rc.o .rc.lib.o .rc.plugin.o: ${COMPILE_STATUS} in="$<"; \ out="$@"; \ if ${RC} ${RCFLAGS} ${CPPFLAGS} -J rc -O coff -o $@ $<; then \ ${COMPILE_OK}; \ else \ ${COMPILE_FAILED}; \ fi .S.o .S.amigalib.o: ${COMPILE_STATUS} |
︙ | ︙ | |||
769 770 771 772 773 774 775 | ${DIR_ENTER}; \ ${MAKE} -s uninstall || exit $$?; \ ${DIR_LEAVE}; \ done for i in "" ${SHARED_LIB}; do \ test x"$$i" = x"" && continue; \ | | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | ${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 -o -f ${DESTDIR}${bindir}/$$i; then \ if : @UNINSTALL_LIB@; then \ ${DELETE_OK}; \ else \ ${DELETE_FAILED}; \ fi \ fi; \ done |
︙ | ︙ |
Modified configure.ac from [a6c1722c25] to [1cc78068e1].
︙ | ︙ | |||
95 96 97 98 99 100 101 | ;; *-msdosdjgpp*) enable_shared="no" enable_threads="no" enable_sockets="no" ;; *-*-mingw*) | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | ;; *-msdosdjgpp*) enable_shared="no" enable_threads="no" enable_sockets="no" ;; *-*-mingw*) LDFLAGS="$LDFLAGS -Wl,--allow-multiple-definition -static-libgcc" LIBS="$LIBS -lversion" AC_SUBST(USE_SRCS_WINDOWS, '${SRCS_WINDOWS}') ;; *-psp-*) AS_IF([test x"$DEVKITPSP" = x""], [ AC_MSG_ERROR([DEVKITPSP is not set! Please set DEVKITPSP.]) |
︙ | ︙ | |||
397 398 399 400 401 402 403 404 405 406 407 408 409 410 | ], [ AC_MSG_RESULT(no) AC_MSG_ERROR(Compiler does not support properties!) ]) AC_CHECK_TOOL(AR, ar) AC_PROG_RANLIB AC_ARG_ENABLE(shared, AS_HELP_STRING([--disable-shared], [do not build shared library])) AS_IF([test x"$enable_shared" != x"no"], [ BUILDSYS_SHARED_LIB AC_SUBST(OBJFW_SHARED_LIB, "${LIB_PREFIX}objfw${LIB_SUFFIX}") AC_SUBST(EXCEPTIONS_LIB_A, "exceptions.lib.a") | > > > > > > | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | ], [ AC_MSG_RESULT(no) AC_MSG_ERROR(Compiler does not support properties!) ]) AC_CHECK_TOOL(AR, ar) AC_PROG_RANLIB case "$host_os" in mingw*) AC_CHECK_TOOL(RC, windres) ;; esac AC_ARG_ENABLE(shared, AS_HELP_STRING([--disable-shared], [do not build shared library])) AS_IF([test x"$enable_shared" != x"no"], [ BUILDSYS_SHARED_LIB AC_SUBST(OBJFW_SHARED_LIB, "${LIB_PREFIX}objfw${LIB_SUFFIX}") AC_SUBST(EXCEPTIONS_LIB_A, "exceptions.lib.a") |
︙ | ︙ | |||
475 476 477 478 479 480 481 482 483 484 485 486 487 488 | #if defined(__GLIBC__) || defined(__MINGW32__) || \ defined(__NEWLIB__) || defined(__MORPHOS__) || defined(__MINT__) egrep_cpp_yes #endif ], [ AC_MSG_RESULT(yes) CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" gnu_source="yes" ], [ AC_MSG_RESULT(no) ]) case "$host_os" in | > | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | #if defined(__GLIBC__) || defined(__MINGW32__) || \ defined(__NEWLIB__) || defined(__MORPHOS__) || defined(__MINT__) egrep_cpp_yes #endif ], [ AC_MSG_RESULT(yes) CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 $CPPFLAGS" CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" gnu_source="yes" ], [ AC_MSG_RESULT(no) ]) case "$host_os" in |
︙ | ︙ | |||
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | dnl Compiler TLS is broken on AArch64 Android with Clang enable_compiler_tls="no" ;; m68k-*-amigaos* | powerpc-*-amigaos*) dnl Compiler TLS is broken on AmigaOS enable_compiler_tls="no" ;; *-*-morphos*) dnl Compiler TLS needs helpers that we don't want in the dnl .library enable_compiler_tls="no" ;; esac | > > > > | 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | dnl Compiler TLS is broken on AArch64 Android with Clang enable_compiler_tls="no" ;; m68k-*-amigaos* | powerpc-*-amigaos*) dnl Compiler TLS is broken on AmigaOS enable_compiler_tls="no" ;; *-*-mingw*) dnl Causes emutls to be pulled in, which pulls in winpthread. enable_compiler_tls="no" ;; *-*-morphos*) dnl Compiler TLS needs helpers that we don't want in the dnl .library enable_compiler_tls="no" ;; esac |
︙ | ︙ | |||
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 | AC_MSG_RESULT($atomic_ops) AC_ARG_ENABLE(files, AS_HELP_STRING([--disable-files], [disable file support])) AS_IF([test x"$enable_files" != x"no"], [ AC_DEFINE(OF_HAVE_FILES, 1, [Whether we have files]) AC_SUBST(USE_SRCS_FILES, '${SRCS_FILES}') AC_SUBST(OFARC, "ofarc") AC_SUBST(OFHASH, "ofhash") case "$host_os" in msdosdjgpp*) dnl DJGPP has the type, but it's not really usable. ;; | > | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | AC_MSG_RESULT($atomic_ops) AC_ARG_ENABLE(files, AS_HELP_STRING([--disable-files], [disable file support])) AS_IF([test x"$enable_files" != x"no"], [ AC_DEFINE(OF_HAVE_FILES, 1, [Whether we have files]) AC_SUBST(USE_SRCS_FILES, '${SRCS_FILES}') AC_SUBST(OBJFW_NEW, "objfw-new") AC_SUBST(OFARC, "ofarc") AC_SUBST(OFHASH, "ofhash") case "$host_os" in msdosdjgpp*) dnl DJGPP has the type, but it's not really usable. ;; |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 | ;; esac AC_CHECK_HEADER(sys/socket.h, [ AC_DEFINE(OF_HAVE_SYS_SOCKET_H, 1, [Whether we have sys/socket.h]) ]) AC_CHECK_HEADER(netinet/in.h, [ 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]) ]) | > | > < < < < < | 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 | ;; esac AC_CHECK_HEADER(sys/socket.h, [ AC_DEFINE(OF_HAVE_SYS_SOCKET_H, 1, [Whether we have sys/socket.h]) ]) AC_CHECK_HEADER(netinet/in.h, [ 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 net/if.h]) AC_CHECK_FUNCS([if_indextoname if_nametoindex]) AC_CHECK_HEADER(sys/un.h, [ AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h]) ]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_SYS_SOCKET_H |
︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 | #endif #ifdef __MINT__ # error Gives invalid argument at runtime #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 | > > > > | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | #endif #ifdef __MINT__ # error Gives invalid argument at runtime #endif ]) 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_ipx.sipx_network, [], [ AC_CHECK_MEMBER(struct sockaddr_ipx.sa_netnum, [], [], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_NETIPX_IPX_H |
︙ | ︙ | |||
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 | 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") | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX]) AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}') ]) ]) AC_CHECK_HEADER(netat/appletalk.h, [ AC_DEFINE(OF_HAVE_NETAT_APPLETALK_H, 1, [Whether we have netat/appletalk.h]) ]) AC_CHECK_HEADER(netatalk/at.h, [ AC_DEFINE(OF_HAVE_NETATALK_AT_H, 1, [Whether we have netatalk/at.h]) ]) AC_CHECK_MEMBER(struct sockaddr_at.sat_addr, [], [ AC_CHECK_MEMBER(struct sockaddr_at.sat_net, [], [], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #if defined(OF_HAVE_NETAT_APPLETALK_H) # include <netat/appletalk.h> #elif defined(OF_HAVE_NETATALK_AT_H) # include <netatalk/at.h> #endif #ifdef _WIN32 # ifdef __MINGW32__ # include <_mingw.h> # ifdef __MINGW64_VERSION_MAJOR # include <winsock2.h> # endif # endif # include <windows.h> # include <atalkwsh.h> #endif ]) ], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #if defined(OF_HAVE_NETAT_APPLETALK_H) # include <netat/appletalk.h> #elif defined(OF_HAVE_NETATALK_AT_H) # include <netatalk/at.h> #endif #ifdef _WIN32 # ifdef __MINGW32__ # include <_mingw.h> # ifdef __MINGW64_VERSION_MAJOR # include <winsock2.h> # endif # endif # include <windows.h> # include <atalkwsh.h> #endif ]) AS_IF([test x"$ac_cv_member_struct_sockaddr_at_sat_addr" = x"yes" \ -o x"$ac_cv_member_struct_sockaddr_at_sat_net" = 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 <atalkwsh.h> #endif #ifdef AF_APPLETALK egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_APPLETALK, 1, [Whether we have AppleTalk]) AC_SUBST(USE_SRCS_APPLETALK, '${SRCS_APPLETALK}') ]) ]) 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") |
︙ | ︙ | |||
1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 | AC_CHECK_FUNCS(SSLCreateContext) ], []) LIBS="$old_LIBS" ]) ]) AS_IF([test x"$with_tls" = x"openssl" \ -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [ case "$host_os" in morphos*) ssl="ssl_shared" crypto="crypto_shared" | > > > > > > > > > > > > > > > > > | 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 | AC_CHECK_FUNCS(SSLCreateContext) ], []) LIBS="$old_LIBS" ]) ]) AS_IF([test x"$with_tls" = x"gnutls" \ -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [ PKG_CHECK_MODULES(gnutls, [gnutls >= 3.5.0], [ AC_DEFINE(HAVE_GNUTLS, 1, [Whether we have GnuTLS]) tls_support="GnuTLS" TLS_CPPFLAGS="$gnutls_CFLAGS $TLS_CPPFLAGS" TLS_LIBS="$gnutls_LIBS $TLS_LIBS" AC_SUBST(OF_GNUTLS_TLS_STREAM_M, "OFGnuTLSTLSStream.m") ], [ dnl Disable default action-if-not-found, which exits dnl configure with an error. : ]) ]) AS_IF([test x"$with_tls" = x"openssl" \ -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [ case "$host_os" in morphos*) ssl="ssl_shared" crypto="crypto_shared" |
︙ | ︙ | |||
1658 1659 1660 1661 1662 1663 1664 | AC_SUBST(OF_OPENSSL_TLS_STREAM_M, "OFOpenSSLTLSStream.m") ]) ], [], [-l$crypto]) ]) | < < < < < < < < < < < < < < < < < | 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 | AC_SUBST(OF_OPENSSL_TLS_STREAM_M, "OFOpenSSLTLSStream.m") ]) ], [], [-l$crypto]) ]) AS_IF([test x"$tls_support" != x"no"], [ AC_SUBST(TLS, "tls") AC_SUBST(TLS_CPPFLAGS) AC_SUBST(TLS_LIBS) AC_DEFINE(HAVE_TLS_SUPPORT, 1, [Whether we have an implementation for TLS]) AC_CONFIG_FILES(src/tls/Info.plist) |
︙ | ︙ | |||
1990 1991 1992 1993 1994 1995 1996 | */ #ifdef __clang__ # define OF_DEALLOC_UNSUPPORTED \ [self doesNotRecognizeSelector: _cmd]; \ \ abort(); \ \ | | > | 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 | */ #ifdef __clang__ # define OF_DEALLOC_UNSUPPORTED \ [self doesNotRecognizeSelector: _cmd]; \ \ abort(); \ \ _Pragma("clang diagnostic push"); \ _Pragma("clang diagnostic ignored \ \"-Wunreachable-code\""); \ [super dealloc]; \ _Pragma("clang diagnostic pop"); #else # define OF_DEALLOC_UNSUPPORTED \ [self doesNotRecognizeSelector: _cmd]; \ \ |
︙ | ︙ |
Modified extra.mk.in from [8ae8820dcd] to [8e59637d10].
︙ | ︙ | |||
39 40 41 42 43 44 45 46 47 48 49 50 51 52 | LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@ LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_AMIGALIB_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OBJC_SYNC = @OBJC_SYNC@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFHTTP_LIBS = @OFHTTP_LIBS@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ | > | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@ LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_AMIGALIB_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OBJC_SYNC = @OBJC_SYNC@ OBJFW_NEW = @OBJFW_NEW@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFHTTP_LIBS = @OFHTTP_LIBS@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ |
︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | TESTS_LIBS = @TESTS_LIBS@ TESTS_STATIC_LIB = @TESTS_STATIC_LIB@ TLS = @TLS@ TLS_CPPFLAGS = @TLS_CPPFLAGS@ TLS_LIBS = @TLS_LIBS@ 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_SOCKETS = @USE_SRCS_SOCKETS@ USE_SRCS_THREADS = @USE_SRCS_THREADS@ USE_SRCS_UNIX_SOCKETS = @USE_SRCS_UNIX_SOCKETS@ USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@ WRAPPER = @WRAPPER@ | > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | TESTS_LIBS = @TESTS_LIBS@ TESTS_STATIC_LIB = @TESTS_STATIC_LIB@ TLS = @TLS@ TLS_CPPFLAGS = @TLS_CPPFLAGS@ TLS_LIBS = @TLS_LIBS@ UNICODE_M = @UNICODE_M@ USE_INCLUDES_ATOMIC = @USE_INCLUDES_ATOMIC@ USE_SRCS_APPLETALK = @USE_SRCS_APPLETALK@ USE_SRCS_FILES = @USE_SRCS_FILES@ USE_SRCS_IPX = @USE_SRCS_IPX@ USE_SRCS_PLUGINS = @USE_SRCS_PLUGINS@ USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@ USE_SRCS_THREADS = @USE_SRCS_THREADS@ USE_SRCS_UNIX_SOCKETS = @USE_SRCS_UNIX_SOCKETS@ USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@ WRAPPER = @WRAPPER@ |
Modified generators/library/LibraryGenerator.m from [0e687972e3] to [69ede2939c].
︙ | ︙ | |||
14 15 16 17 18 19 20 | */ #include "config.h" #import "OFApplication.h" #import "OFFile.h" #import "OFFileManager.h" | | | | | | | | | | | | | | | | | | | | 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 | */ #include "config.h" #import "OFApplication.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFURI.h" #import "OFXMLElement.h" #import "FuncArrayGenerator.h" #import "GlueGenerator.h" #import "LinkLibGenerator.h" @interface LibraryGenerator: OFObject <OFApplicationDelegate> @end OF_APPLICATION_DELEGATE(LibraryGenerator) @implementation LibraryGenerator - (void)applicationDidFinishLaunching { OFURI *sourcesURI = [[OFFileManager defaultManager].currentDirectoryURI URIByAppendingPathComponent: @"../../src"]; OFURI *runtimeLibraryURI = [sourcesURI URIByAppendingPathComponent: @"runtime/amiga-library.xml"]; OFURI *runtimeLinkLibURI = [sourcesURI URIByAppendingPathComponent: @"runtime/linklib/linklib.m"]; OFURI *runtimeGlueHeaderURI = [sourcesURI URIByAppendingPathComponent: @"runtime/amiga-glue.h"]; OFURI *runtimeGlueURI = [sourcesURI URIByAppendingPathComponent: @"runtime/amiga-glue.m"]; OFURI *runtimeFuncArrayURI = [sourcesURI URIByAppendingPathComponent: @"runtime/amiga-funcarray.inc"]; OFXMLElement *runtimeLibrary = [OFXMLElement elementWithStream: [OFFile fileWithPath: runtimeLibraryURI.fileSystemRepresentation mode: @"r"]]; OFFile *runtimeLinkLib = [OFFile fileWithPath: runtimeLinkLibURI.fileSystemRepresentation mode: @"w"]; OFFile *runtimeGlueHeader = [OFFile fileWithPath: runtimeGlueHeaderURI.fileSystemRepresentation mode: @"w"]; OFFile *runtimeGlue = [OFFile fileWithPath: runtimeGlueURI.fileSystemRepresentation mode: @"w"]; OFFile *runtimeFuncArray = [OFFile fileWithPath: runtimeFuncArrayURI.fileSystemRepresentation mode: @"w"]; LinkLibGenerator *runtimeLinkLibGenerator = [[[LinkLibGenerator alloc] initWithLibrary: runtimeLibrary implementation: runtimeLinkLib] autorelease]; GlueGenerator *runtimeGlueGenerator = [[[GlueGenerator alloc] initWithLibrary: runtimeLibrary header: runtimeGlueHeader |
︙ | ︙ |
Modified generators/unicode/TableGenerator.m from [442fb49647] to [c1835e042f].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #include "config.h" #include <string.h> #import "OFString.h" #import "OFArray.h" #import "OFApplication.h" | | | | | 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 | #include "config.h" #include <string.h> #import "OFString.h" #import "OFArray.h" #import "OFApplication.h" #import "OFURI.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFHTTPClient.h" #import "OFFile.h" #import "OFStdIOStream.h" #import "OFOutOfRangeException.h" #import "TableGenerator.h" #import "copyright.h" static OFString *const unicodeDataURI = @"http://www.unicode.org/Public/UNIDATA/UnicodeData.txt"; static OFString *const caseFoldingURI = @"http://www.unicode.org/Public/UNIDATA/CaseFolding.txt"; OF_APPLICATION_DELEGATE(TableGenerator) @implementation TableGenerator - (instancetype)init { |
︙ | ︙ | |||
64 65 66 67 68 69 70 | - (void)applicationDidFinishLaunching { OFHTTPRequest *request; [OFStdOut writeString: @"Downloading UnicodeData.txt…"]; _state = stateUnicodeData; | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | - (void)applicationDidFinishLaunching { OFHTTPRequest *request; [OFStdOut writeString: @"Downloading UnicodeData.txt…"]; _state = stateUnicodeData; request = [OFHTTPRequest requestWithURI: [OFURI URIWithString: unicodeDataURI]]; [_HTTPClient asyncPerformRequest: request]; } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response exception: (id)exception |
︙ | ︙ | |||
133 134 135 136 137 138 139 | OFArray *decomposed = [[components objectAtIndex: 5] componentsSeparatedByString: @" "]; bool compat = false; OFMutableString *string; if ([decomposed.firstObject hasPrefix: @"<"]) { decomposed = [decomposed objectsInRange: | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | OFArray *decomposed = [[components objectAtIndex: 5] componentsSeparatedByString: @" "]; bool compat = false; OFMutableString *string; if ([decomposed.firstObject hasPrefix: @"<"]) { decomposed = [decomposed objectsInRange: OFMakeRange(1, decomposed.count - 1)]; compat = true; } string = [OFMutableString string]; for (OFString *character in decomposed) { OFUnichar unichar = (OFUnichar)[character |
︙ | ︙ | |||
164 165 166 167 168 169 170 | [self applyDecompositionRecursivelyForTable: _decompositionTable]; [self applyDecompositionRecursivelyForTable: _decompositionCompatTable]; [OFStdOut writeLine: @" done"]; [OFStdOut writeString: @"Downloading CaseFolding.txt…"]; _state = stateCaseFolding; | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | [self applyDecompositionRecursivelyForTable: _decompositionTable]; [self applyDecompositionRecursivelyForTable: _decompositionCompatTable]; [OFStdOut writeLine: @" done"]; [OFStdOut writeString: @"Downloading CaseFolding.txt…"]; _state = stateCaseFolding; request = [OFHTTPRequest requestWithURI: [OFURI URIWithString: caseFoldingURI]]; [_HTTPClient asyncPerformRequest: request]; } - (void)parseCaseFolding: (OFHTTPResponse *)response { OFString *line; |
︙ | ︙ | |||
266 267 268 269 270 271 272 | objc_autoreleasePoolPop(pool); } } while (!done); } - (void)writeFiles { | | | | | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | objc_autoreleasePoolPop(pool); } } while (!done); } - (void)writeFiles { OFURI *URI; [OFStdOut writeString: @"Writing files…"]; URI = [OFURI fileURIWithPath: @"../../src/unicode.m"]; [self writeTablesToFile: URI.fileSystemRepresentation]; URI = [OFURI fileURIWithPath: @"../../src/unicode.h"]; [self writeHeaderToFile: URI.fileSystemRepresentation]; [OFStdOut writeLine: @" done"]; [OFApplication terminate]; } - (void)writeTablesToFile: (OFString *)path |
︙ | ︙ |
Modified objfw.spec from [01416894bd] to [218ec62f80].
︙ | ︙ | |||
28 29 30 31 32 33 34 | URL: https://objfw.nil.im Source0: objfw-%{version}.tar.gz BuildRequires: autoconf BuildRequires: automake BuildRequires: clang BuildRequires: make | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | URL: https://objfw.nil.im Source0: objfw-%{version}.tar.gz BuildRequires: autoconf BuildRequires: automake BuildRequires: clang BuildRequires: make BuildRequires: pkgconfig(gnutls) Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfw_pkgname}-devel = %{version}-%{release} Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwrt_pkgname}-devel = %{version}-%{release} Requires: ofarc%{_isa} = %{version}-%{release} Requires: ofdns%{_isa} = %{version}-%{release} Requires: ofhash%{_isa} = %{version}-%{release} |
︙ | ︙ | |||
85 86 87 88 89 90 91 | %description -n %{libobjfwrt_pkgname}-devel The %{libobjfwrt_pkgname}-devel package contains header files and libraries for ObjFW's Objective-C runtime library. %package -n %{libobjfwtls_pkgname} Summary: TLS support for ObjFW | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | %description -n %{libobjfwrt_pkgname}-devel The %{libobjfwrt_pkgname}-devel package contains header files and libraries for ObjFW's Objective-C runtime library. %package -n %{libobjfwtls_pkgname} Summary: TLS support for ObjFW Requires: gnutls%{_isa} >= 3.0.5 %description -n %{libobjfwtls_pkgname} The %{libobjfwtls_pkgname} package contains TLS support for ObjFW %package -n %{libobjfwtls_pkgname}-devel Summary: Header files and libraries for %{libobjfwtls_pkgname} Requires: %{libobjfwtls_pkgname}%{_isa} = %{version}-%{release} |
︙ | ︙ | |||
134 135 136 137 138 139 140 | %package -n ofhttp Summary: Command line downloader for HTTP(S) Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwtls_pkgname}%{_isa} = %{version}-%{release} %description -n ofhttp | | | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | %package -n ofhttp Summary: Command line downloader for HTTP(S) Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwtls_pkgname}%{_isa} = %{version}-%{release} %description -n ofhttp ofhttp is a command line downloader for HTTP and HTTPS using ObjFW's OFHTTPClient class. It supports all features one would expect from a modern command line downloader such as resuming of downloads, using a SOCKS5 proxy, a modern terminal-based UI, etc. %prep %autosetup ./autogen.sh %build %configure OBJC=clang --disable-rpath |
︙ | ︙ |
Modified src/Makefile from [e928ef8188] to [68d38296ac].
︙ | ︙ | |||
30 31 32 33 34 35 36 | OFCountedSet.m \ OFData.m \ OFData+ASN1DERParsing.m \ OFData+CryptographicHashing.m \ OFData+MessagePackParsing.m \ OFDate.m \ OFDictionary.m \ | < < | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | OFCountedSet.m \ OFData.m \ OFData+ASN1DERParsing.m \ OFData+CryptographicHashing.m \ OFData+MessagePackParsing.m \ OFDate.m \ OFDictionary.m \ OFEnumerator.m \ OFFileManager.m \ OFGZIPStream.m \ OFHMAC.m \ OFINICategory.m \ OFINIFile.m \ OFInflate64Stream.m \ OFInflateStream.m \ OFInvocation.m \ OFLHAArchive.m \ OFLHAArchiveEntry.m \ OFList.m \ OFLocale.m \ |
︙ | ︙ | |||
59 60 61 62 63 64 65 | OFMutableDictionary.m \ OFMutableLHAArchiveEntry.m \ OFMutablePair.m \ OFMutableSet.m \ OFMutableString.m \ OFMutableTarArchiveEntry.m \ OFMutableTriple.m \ | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | OFMutableDictionary.m \ OFMutableLHAArchiveEntry.m \ OFMutablePair.m \ OFMutableSet.m \ OFMutableString.m \ OFMutableTarArchiveEntry.m \ OFMutableTriple.m \ OFMutableURI.m \ OFMutableZIPArchiveEntry.m \ OFNotification.m \ OFNotificationCenter.m \ OFNull.m \ OFNumber.m \ OFObject.m \ OFObject+KeyValueCoding.m \ |
︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 | OFSet.m \ OFSortedList.m \ OFStdIOStream.m \ OFStream.m \ OFString.m \ OFString+CryptographicHashing.m \ OFString+JSONParsing.m \ OFString+PropertyListParsing.m \ OFString+Serialization.m \ | > < | | | 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 | OFSet.m \ OFSortedList.m \ OFStdIOStream.m \ OFStream.m \ OFString.m \ OFString+CryptographicHashing.m \ OFString+JSONParsing.m \ OFString+PercentEncoding.m \ OFString+PropertyListParsing.m \ OFString+Serialization.m \ OFString+XMLEscaping.m \ OFString+XMLUnescaping.m \ ${OF_SUBPROCESS_M} \ OFSettings.m \ OFSystemInfo.m \ OFTarArchive.m \ OFTarArchiveEntry.m \ OFThread.m \ OFTimer.m \ OFTriple.m \ OFURI.m \ OFURIHandler.m \ OFUUID.m \ OFValue.m \ OFXMLAttribute.m \ OFXMLCDATA.m \ OFXMLCharacters.m \ OFXMLComment.m \ OFXMLElement.m \ |
︙ | ︙ | |||
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | OFHTTPServer.m \ OFSequencedPacketSocket.m \ OFSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFTLSStream.m \ OFUDPSocket.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \ OFUNIXStreamSocket.m SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFPlainCondition.m \ OFPlainMutex.m \ OFPlainThread.m \ OFRecursiveMutex.m \ OFTLSKey.m | > > < | > > > > > | 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 | OFHTTPServer.m \ OFSequencedPacketSocket.m \ OFSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFTLSStream.m \ OFUDPSocket.m \ ${USE_SRCS_APPLETALK} \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} SRCS_APPLETALK = OFDDPSocket.m SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \ OFUNIXStreamSocket.m SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFPlainCondition.m \ OFPlainMutex.m \ OFPlainThread.m \ OFRecursiveMutex.m \ OFTLSKey.m SRCS_WINDOWS = OFWindowsRegistryKey.m INCLUDES_ATOMIC = OFAtomic.h \ platform/GCC4/OFAtomic.h \ platform/GCC4.7/OFAtomic.h \ platform/PowerPC/OFAtomic.h \ platform/macOS/OFAtomic.h \ platform/x86/OFAtomic.h INCLUDES := ${SRCS:.m=.h} \ OFASN1DERRepresentation.h \ OFArchiveEntry.h \ OFCollection.h \ OFCryptographicHash.h \ OFJSONRepresentation.h \ OFKernelEventObserver.h \ OFKeyValueCoding.h \ OFLocking.h \ OFMessagePackRepresentation.h \ OFMutableArchiveEntry.h \ ObjFW.h \ macros.h \ objfw-defs.h \ platform.h \ ${USE_INCLUDES_ATOMIC} SRCS += OFASPrintF.m \ OFAdjacentArray.m \ OFAdjacentSubarray.m \ OFArchiveURIHandler.m \ OFBase64.m \ OFBitSetCharacterSet.m \ OFBytesValue.m \ OFCRC16.m \ OFCRC32.m \ OFCountedMapTableSet.m \ OFEmbeddedURIHandler.m \ OFHuffmanTree.m \ OFINIFileSettings.m \ OFInvertedCharacterSet.m \ OFLHADecompressingStream.m \ OFMapTableDictionary.m \ OFMapTableSet.m \ OFMutableAdjacentArray.m \ OFMutableMapTableDictionary.m \ OFMutableMapTableSet.m \ |
︙ | ︙ | |||
216 217 218 219 220 221 222 | OFSizeValue.m \ OFStrPTime.m \ OFSubarray.m \ OFUTF8String.m \ ${LIBBASES_M} \ ${RUNTIME_AUTORELEASE_M} \ ${RUNTIME_INSTANCE_M} \ | | | > | | < > > > > > > > | 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 | OFSizeValue.m \ OFStrPTime.m \ OFSubarray.m \ OFUTF8String.m \ ${LIBBASES_M} \ ${RUNTIME_AUTORELEASE_M} \ ${RUNTIME_INSTANCE_M} \ ${UNICODE_M} SRCS_FILES += OFFileURIHandler.m SRCS_SOCKETS += OFAsyncIPSocketConnector.m \ OFDNSResolverSettings.m \ ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \ OFHTTPURIHandler.m \ OFHostAddressResolver.m \ OFKernelEventObserver.m \ ${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \ ${OF_POLL_KERNEL_EVENT_OBSERVER_M} \ ${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \ OFTCPSocketSOCKS5Connector.m SRCS_WINDOWS += platform/Windows/OFWin32ConsoleStdIOStream.m \ versioninfo.rc OBJS_EXTRA = exceptions/exceptions.a \ encodings/encodings.a \ forwarding/forwarding.a LIB_OBJS_EXTRA = exceptions/exceptions.lib.a \ encodings/encodings.lib.a \ forwarding/forwarding.lib.a include ../buildsys.mk CPPFLAGS += -I. -I.. -Iexceptions -Iruntime LD = ${OBJC} FRAMEWORK_LIBS := -Fruntime \ ${RUNTIME_FRAMEWORK_LIBS} \ ${REEXPORT_RUNTIME_FRAMEWORK} \ ${LIBS} LIBS := -Lruntime ${RUNTIME_LIBS} ${REEXPORT_RUNTIME} ${LIBS} RCFLAGS = --use-temp-file \ -DOBJFW_LIB_MAJOR=${OBJFW_LIB_MAJOR} \ -DOBJFW_LIB_MINOR=${OBJFW_LIB_MINOR} \ -DOBJFW_LIB_VERSION=\"${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}\" \ -DOBJFW_SHARED_LIB=\"${OBJFW_SHARED_LIB}\" |
Modified src/OFASN1BitString.m from [5ba0c45db7] to [bf8a8b6b76].
︙ | ︙ | |||
87 88 89 90 91 92 93 | @throw [OFInvalidFormatException exception]; if (SIZE_MAX / 8 < count - 1) @throw [OFOutOfRangeException exception]; length = (count - 1) * 8; bitString = [DEREncodedContents subdataWithRange: | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | @throw [OFInvalidFormatException exception]; if (SIZE_MAX / 8 < count - 1) @throw [OFOutOfRangeException exception]; length = (count - 1) * 8; bitString = [DEREncodedContents subdataWithRange: OFMakeRange(1, count - 1)]; if (unusedBits != 0) length -= unusedBits; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ |
Modified src/OFASN1Value.m from [7ec68174be] to [789f3d1ac5].
︙ | ︙ | |||
99 100 101 102 103 104 105 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); | | | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddByte(&hash, _tagClass & 0xFF); OFHashAddByte(&hash, _tagNumber & 0xFF); OFHashAddByte(&hash, _constructed); OFHashAddHash(&hash, _DEREncodedContents.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ |
Modified src/OFASPrintF.m from [31044637f2] to [882db55cea].
︙ | ︙ | |||
578 579 580 581 582 583 584 | 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 ".". */ | | | 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | 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 decimalSeparator]; if (!ctx->useLocale && point != nil && ![point isEqual: @"."]) { void *pool = objc_autoreleasePoolPush(); char *tmp2; @try { OFMutableString *tmpStr = [OFMutableString |
︙ | ︙ |
Modified src/OFApplication.m from [bde88848cd] to [1a4d3713d8].
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 47 | #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" | > < | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #import "OFRunLoop.h" #import "OFSandbox.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFThread+Private.h" #import "OFThread.h" #import "OFActivateSandboxFailedException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #if defined(OF_MACOS) # include <crt_externs.h> #elif defined(OF_WINDOWS) # include <windows.h> extern int _CRT_glob; extern void __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); |
︙ | ︙ | |||
650 651 652 653 654 655 656 | } sandbox->_unveiledPathsIndex = unveiledPathsCount; promises = [sandbox.pledgeString cStringWithEncoding: encoding]; if (pledge(promises, NULL) != 0) | | | 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 | } sandbox->_unveiledPathsIndex = unveiledPathsCount; promises = [sandbox.pledgeString cStringWithEncoding: encoding]; if (pledge(promises, NULL) != 0) @throw [OFActivateSandboxFailedException exceptionWithSandbox: sandbox errNo: errno]; objc_autoreleasePoolPop(pool); if (_activeSandbox == nil) _activeSandbox = [sandbox retain]; |
︙ | ︙ | |||
678 679 680 681 682 683 684 | if (sandbox.unveiledPaths.count != 0) @throw [OFInvalidArgumentException exception]; promises = [sandbox.pledgeString cStringWithEncoding: [OFLocale encoding]]; if (pledge(NULL, promises) != 0) | | | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 | if (sandbox.unveiledPaths.count != 0) @throw [OFInvalidArgumentException exception]; promises = [sandbox.pledgeString cStringWithEncoding: [OFLocale encoding]]; if (pledge(NULL, promises) != 0) @throw [OFActivateSandboxFailedException exceptionWithSandbox: sandbox errNo: errno]; objc_autoreleasePoolPop(pool); if (_activeSandboxForChildProcesses == nil) _activeSandboxForChildProcesses = [sandbox retain]; # endif } #endif @end |
Added src/OFArchiveEntry.h version [70aea150d9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Copyright (c) 2008-2022 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 "OFString.h" OF_ASSUME_NONNULL_BEGIN @class OFDate; @class OFNumber; /** * @protocol OFArchiveEntry OFArchiveEntry.h ObjFW/OFArchiveEntry.h * * @brief A class which represents an entry in an archive. */ @protocol OFArchiveEntry <OFObject> /** * @brief The file name of the entry. */ @property (readonly, copy, nonatomic) OFString *fileName; /** * @brief The compressed size of the entry's file. */ @property (readonly, nonatomic) unsigned long long compressedSize; /** * @brief The uncompressed size of the entry's file. */ @property (readonly, nonatomic) unsigned long long uncompressedSize; @optional /** * @brief The modification date of the file. */ @property (readonly, retain, nonatomic) OFDate *modificationDate; /** * @brief The comment of the entry's file. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *fileComment; /** * @brief The POSIX permissions of the file. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFNumber *POSIXPermissions; /** * @brief The file owner's account ID. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFNumber *ownerAccountID; /** * @brief The file owner's group account ID. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFNumber *groupOwnerAccountID; /** * @brief The file owner's account name. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFString *ownerAccountName; /** * @brief The file owner's group account name. */ @property OF_NULLABLE_PROPERTY (readonly, retain, nonatomic) OFString *groupOwnerAccountName; @end OF_ASSUME_NONNULL_END #import "OFMutableArchiveEntry.h" |
Added src/OFArchiveURIHandler.h version [7c81cf8db2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Copyright (c) 2008-2022 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 "OFURIHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFArchiveURIHandler: OFURIHandler @end #ifdef __cplusplus extern "C" { #endif extern OFURI *OFArchiveURIHandlerURIForFileInArchive(OFString *, OFString *, OFURI *); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Added src/OFArchiveURIHandler.m version [010e8050b6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Copyright (c) 2008-2022 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 "OFArchiveURIHandler.h" #import "OFCharacterSet.h" #import "OFGZIPStream.h" #import "OFLHAArchive.h" #import "OFStream.h" #import "OFTarArchive.h" #import "OFURI.h" #import "OFZIPArchive.h" #import "OFInvalidArgumentException.h" #import "OFOpenItemFailedException.h" @interface OFArchiveURIHandlerPathAllowedCharacterSet: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, OFUnichar); } @end static OFCharacterSet *pathAllowedCharacters; static void initPathAllowedCharacters(void) { pathAllowedCharacters = [[OFArchiveURIHandlerPathAllowedCharacterSet alloc] init]; } @implementation OFArchiveURIHandler - (OFStream *)openItemAtURI: (OFURI *)URI mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFString *scheme = URI.scheme; OFString *percentEncodedPath, *path; size_t pos; OFURI *archiveURI; OFStream *stream; if (URI.host != nil || URI.port != nil || URI.user != nil || URI.password != nil || URI.query != nil || URI.fragment != nil) @throw [OFInvalidArgumentException exception]; if (![mode isEqual: @"r"]) /* * Writing has some implications that are not decided yet: Will * it always append to an archive? What happens if the file * already exists? */ @throw [OFInvalidArgumentException exception]; /* * GZIP only compresses one file and thus has no path inside an * archive. */ if ([scheme isEqual: @"gzip"]) { stream = [OFURIHandler openItemAtURI: [OFURI URIWithString: URI.path] mode: @"r"]; stream = [OFGZIPStream streamWithStream: stream mode: @"r"]; goto end; } percentEncodedPath = URI.percentEncodedPath; pos = [percentEncodedPath rangeOfString: @"!"].location; if (pos == OFNotFound) @throw [OFInvalidArgumentException exception]; archiveURI = [OFURI URIWithString: [percentEncodedPath substringWithRange: OFMakeRange(0, pos)] .stringByRemovingPercentEncoding]; path = [percentEncodedPath substringWithRange: OFMakeRange(pos + 1, percentEncodedPath.length - pos - 1)] .stringByRemovingPercentEncoding; if ([scheme isEqual: @"lha"]) { OFLHAArchive *archive = [OFLHAArchive archiveWithURI: archiveURI mode: @"r"]; OFLHAArchiveEntry *entry; while ((entry = [archive nextEntry]) != nil) { if ([entry.fileName isEqual: path]) { stream = [archive streamForReadingCurrentEntry]; goto end; } } @throw [OFOpenItemFailedException exceptionWithURI: URI mode: mode errNo: ENOENT]; } else if ([scheme isEqual: @"tar"]) { OFTarArchive *archive = [OFTarArchive archiveWithURI: archiveURI mode: @"r"]; OFTarArchiveEntry *entry; while ((entry = [archive nextEntry]) != nil) { if ([entry.fileName isEqual: path]) { stream = [archive streamForReadingCurrentEntry]; goto end; } } @throw [OFOpenItemFailedException exceptionWithURI: URI mode: mode errNo: ENOENT]; } else if ([scheme isEqual: @"zip"]) { OFZIPArchive *archive = [OFZIPArchive archiveWithURI: archiveURI mode: @"r"]; stream = [archive streamForReadingFile: path]; } else @throw [OFInvalidArgumentException exception]; end: stream = [stream retain]; objc_autoreleasePoolPop(pool); return [stream autorelease]; } @end @implementation OFArchiveURIHandlerPathAllowedCharacterSet - (instancetype)init { self = [super init]; @try { _characterSet = [[OFCharacterSet URIPathAllowedCharacterSet] retain]; _characterIsMember = (bool (*)(id, SEL, OFUnichar)) [_characterSet methodForSelector: @selector(characterIsMember:)]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_characterSet release]; [super dealloc]; } - (bool)characterIsMember: (OFUnichar)character { return (character != '!' && _characterIsMember(_characterSet, @selector(characterIsMember:), character)); } @end OFURI * OFArchiveURIHandlerURIForFileInArchive(OFString *scheme, OFString *pathInArchive, OFURI *archiveURI) { static OFOnceControl onceControl = OFOnceControlInitValue; OFMutableURI *ret = [OFMutableURI URIWithScheme: scheme]; void *pool = objc_autoreleasePoolPush(); OFString *archiveURIString; OFOnce(&onceControl, initPathAllowedCharacters); pathInArchive = [pathInArchive stringByAddingPercentEncodingWithAllowedCharacters: pathAllowedCharacters]; archiveURIString = [archiveURI.string stringByAddingPercentEncodingWithAllowedCharacters: pathAllowedCharacters]; ret.percentEncodedPath = [OFString stringWithFormat: @"%@!%@", archiveURIString, pathInArchive]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } |
Modified src/OFArray.m from [7359b37923] to [c89de989b4].
︙ | ︙ | |||
238 239 240 241 242 243 244 | - (id const *)objects { size_t count = self.count; id *buffer = OFAllocMemory(count, sizeof(id)); id const *ret; @try { | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | - (id const *)objects { size_t count = self.count; id *buffer = OFAllocMemory(count, sizeof(id)); id const *ret; @try { [self getObjects: buffer inRange: OFMakeRange(0, count)]; ret = [[OFData dataWithItemsNoCopy: buffer count: count itemSize: sizeof(id) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); |
︙ | ︙ | |||
531 532 533 534 535 536 537 | if (self.count == 0) return @"()"; pool = objc_autoreleasePoolPush(); ret = [[self componentsJoinedByString: @",\n"] mutableCopy]; @try { | | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | if (self.count == 0) return @"()"; pool = objc_autoreleasePoolPush(); ret = [[self componentsJoinedByString: @",\n"] mutableCopy]; @try { [ret insertString: @"(\n" atIndex: 0]; [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @"\n)"]; } @catch (id e) { [ret release]; @throw e; } |
︙ | ︙ | |||
747 748 749 750 751 752 753 | return new; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { | | | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | return new; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { OFRange range = OFMakeRange(state->state, count); if (range.length > SIZE_MAX - range.location) @throw [OFOutOfRangeException exception]; if (range.location + range.length > self.count) range.length = self.count - range.location; |
︙ | ︙ |
Renamed and modified src/OFIPSocketAsyncConnector.h [248ffd2ce4] to src/OFAsyncIPSocketConnector.h [00aff2415e].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #import "OFDNSResolver.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.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 | #import "OFDNSResolver.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" OF_ASSUME_NONNULL_BEGIN @protocol OFAsyncIPSocketConnecting - (bool)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (void)of_closeSocket; @end @interface OFAsyncIPSocketConnector: OFObject <OFRunLoopConnectDelegate, OFDNSResolverHostDelegate> { id _socket; OFString *_host; uint16_t _port; id _Nullable _delegate; id _Nullable _block; |
︙ | ︙ |
Renamed and modified src/OFIPSocketAsyncConnector.m [e235fd33e4] to src/OFAsyncIPSocketConnector.m [b9084cfb8c].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * file. */ #include "config.h" #include <errno.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 | * file. */ #include "config.h" #include <errno.h> #import "OFAsyncIPSocketConnector.h" #import "OFData.h" #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFConnectIPSocketFailedException.h" #import "OFInvalidFormatException.h" @implementation OFAsyncIPSocketConnector - (instancetype)initWithSocket: (id)sock host: (OFString *)host port: (uint16_t)port delegate: (id)delegate block: (id)block { self = [super init]; |
︙ | ︙ | |||
122 123 124 125 126 127 128 | } [self didConnect]; } - (id)of_connectionFailedExceptionForErrNo: (int)errNo { | | | | | | | | 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 | } [self didConnect]; } - (id)of_connectionFailedExceptionForErrNo: (int)errNo { return [OFConnectIPSocketFailedException exceptionWithHost: _host port: _port socket: _socket errNo: errNo]; } - (void)tryNextAddressWithRunLoopMode: (OFRunLoopMode)runLoopMode { OFSocketAddress address = *(const OFSocketAddress *) [_socketAddresses itemAtIndex: _socketAddressesIndex++]; int errNo; OFSocketAddressSetIPPort(&address, _port); if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectIPSocketFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return; } |
︙ | ︙ | |||
183 184 185 186 187 188 189 | delegate: self]; return; } else { #endif [_socket of_closeSocket]; if (_socketAddressesIndex >= _socketAddresses.count) { | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | delegate: self]; return; } else { #endif [_socket of_closeSocket]; if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectIPSocketFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return; } |
︙ | ︙ |
Modified src/OFColor.m from [5191910ddc] to [ff82ab6aae].
︙ | ︙ | |||
124 125 126 127 128 129 130 | unsigned long hash; float tmp; OFHashInit(&hash); tmp = OFToLittleEndianFloat(_red); for (uint_fast8_t i = 0; i < sizeof(float); i++) | | | | | | 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 | unsigned long hash; float tmp; OFHashInit(&hash); tmp = OFToLittleEndianFloat(_red); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAddByte(&hash, ((char *)&tmp)[i]); tmp = OFToLittleEndianFloat(_green); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAddByte(&hash, ((char *)&tmp)[i]); tmp = OFToLittleEndianFloat(_blue); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAddByte(&hash, ((char *)&tmp)[i]); tmp = OFToLittleEndianFloat(_alpha); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAddByte(&hash, ((char *)&tmp)[i]); OFHashFinalize(&hash); return hash; } - (void)getRed: (float *)red |
︙ | ︙ |
Modified src/OFCondition.h from [b8eb2412a1] to [2de2d56fa5].
︙ | ︙ | |||
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 | /** * @brief Blocks the current thread until another thread calls @ref signal or * @ref broadcast. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref wait returned! */ - (void)wait; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. */ - (void)waitForConditionOrExecSignal: (ULONG *)signalMask; #endif /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitForTimeInterval: returned! * * @param timeInterval The time interval until the timeout is reached * @return Whether the condition has been signaled */ - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param timeInterval The time interval until the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received */ - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval orExecSignal: (ULONG *)signalMask; #endif /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitUntilDate: returned! * * @param date The date at which the timeout is reached * @return Whether the condition has been signaled */ - (bool)waitUntilDate: (OFDate *)date; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param date The date at which the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received */ - (bool)waitUntilDate: (OFDate *)date orExecSignal: (ULONG *)signalMask; #endif /** * @brief Signals the next waiting thread to continue. */ - (void)signal; /** * @brief Signals all threads to continue. */ - (void)broadcast; @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > | 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 | /** * @brief Blocks the current thread until another thread calls @ref signal or * @ref broadcast. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref wait returned! * * @throw OFWaitForConditionFailedException Waiting for the condition failed */ - (void)wait; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @throw OFWaitForConditionFailedException Waiting for the condition failed */ - (void)waitForConditionOrExecSignal: (ULONG *)signalMask; #endif /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitForTimeInterval: returned! * * @param timeInterval The time interval until the timeout is reached * @return Whether the condition has been signaled * @throw OFWaitForConditionFailedException Waiting for the condition failed */ - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param timeInterval The time interval until the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received * @throw OFWaitForConditionFailedException Waiting for the condition failed */ - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval orExecSignal: (ULONG *)signalMask; #endif /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitUntilDate: returned! * * @param date The date at which the timeout is reached * @return Whether the condition has been signaled * @throw OFWaitForConditionFailedException Waiting for the condition failed */ - (bool)waitUntilDate: (OFDate *)date; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param date The date at which the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received * @throw OFWaitForConditionFailedException Waiting for the condition failed */ - (bool)waitUntilDate: (OFDate *)date orExecSignal: (ULONG *)signalMask; #endif /** * @brief Signals the next waiting thread to continue. * * @throw OFSignalConditionFailedException Signaling the condition failed */ - (void)signal; /** * @brief Signals all threads to continue. * * @throw OFBroadcastConditionFailedException Broadcasting the condition failed */ - (void)broadcast; @end OF_ASSUME_NONNULL_END |
Modified src/OFCondition.m from [8de6591c81] to [6291bb097b].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #include "config.h" #include <errno.h> #import "OFCondition.h" #import "OFDate.h" | < | < > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include "config.h" #include <errno.h> #import "OFCondition.h" #import "OFDate.h" #import "OFBroadcastConditionFailedException.h" #import "OFConditionStillWaitingException.h" #import "OFInitializationFailedException.h" #import "OFSignalConditionFailedException.h" #import "OFWaitForConditionFailedException.h" @implementation OFCondition + (instancetype)condition { return [[[self alloc] init] autorelease]; } |
︙ | ︙ | |||
64 65 66 67 68 69 70 | } - (void)wait { int error = OFPlainConditionWait(&_condition, &_mutex); if (error != 0) | | | | | | 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 | } - (void)wait { int error = OFPlainConditionWait(&_condition, &_mutex); if (error != 0) @throw [OFWaitForConditionFailedException exceptionWithCondition: self errNo: error]; } #ifdef OF_AMIGAOS - (void)waitForConditionOrExecSignal: (ULONG *)signalMask { int error = OFPlainConditionWaitOrExecSignal(&_condition, &_mutex, signalMask); if (error != 0) @throw [OFWaitForConditionFailedException exceptionWithCondition: self errNo: error]; } #endif - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval { int error = OFPlainConditionTimedWait(&_condition, &_mutex, timeInterval); if (error == ETIMEDOUT) return false; if (error != 0) @throw [OFWaitForConditionFailedException exceptionWithCondition: self errNo: error]; return true; } #ifdef OF_AMIGAOS - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval orExecSignal: (ULONG *)signalMask { int error = OFPlainConditionTimedWaitOrExecSignal(&_condition, &_mutex, timeInterval, signalMask); if (error == ETIMEDOUT) return false; if (error != 0) @throw [OFWaitForConditionFailedException exceptionWithCondition: self errNo: error]; return true; } #endif |
︙ | ︙ | |||
135 136 137 138 139 140 141 | #endif - (void)signal { int error = OFPlainConditionSignal(&_condition); if (error != 0) | | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | #endif - (void)signal { int error = OFPlainConditionSignal(&_condition); if (error != 0) @throw [OFSignalConditionFailedException exceptionWithCondition: self errNo: error]; } - (void)broadcast { int error = OFPlainConditionBroadcast(&_condition); if (error != 0) @throw [OFBroadcastConditionFailedException exceptionWithCondition: self errNo: error]; } @end |
Modified src/OFConstantString.m from [d768085319] to [3adc07df05].
︙ | ︙ | |||
352 353 354 355 356 357 358 | - (OFString *)stringByAppendingPathExtension: (OFString *)extension { [self finishInitialization]; return [self stringByAppendingPathExtension: extension]; } | < < < < < < | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | - (OFString *)stringByAppendingPathExtension: (OFString *)extension { [self finishInitialization]; return [self stringByAppendingPathExtension: extension]; } - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { [self finishInitialization]; return [self stringByReplacingOccurrencesOfString: string withString: replacement]; } |
︙ | ︙ | |||
479 480 481 482 483 484 485 | - (long long)longLongValue { [self finishInitialization]; return self.longLongValue; } | | | | 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 | - (long long)longLongValue { [self finishInitialization]; return self.longLongValue; } - (long long)longLongValueWithBase: (unsigned char)base { [self finishInitialization]; return [self longLongValueWithBase: base]; } - (unsigned long long)unsignedLongLongValue { [self finishInitialization]; return self.unsignedLongLongValue; } - (unsigned long long)unsignedLongLongValueWithBase: (unsigned char)base { [self finishInitialization]; return [self unsignedLongLongValueWithBase: base]; } - (float)floatValue { |
︙ | ︙ | |||
587 588 589 590 591 592 593 | - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding { [self finishInitialization]; [self writeToFile: path encoding: encoding]; } #endif | | | | | | 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 | - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding { [self finishInitialization]; [self writeToFile: path encoding: encoding]; } #endif - (void)writeToURI: (OFURI *)URI { [self finishInitialization]; [self writeToURI: URI]; } - (void)writeToURI: (OFURI *)URI encoding: (OFStringEncoding)encoding { [self finishInitialization]; [self writeToURI: URI encoding: encoding]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (OFStringLineEnumerationBlock)block { [self finishInitialization]; [self enumerateLinesUsingBlock: block]; } #endif @end |
Modified src/OFCryptographicHash.h from [21f208b184] to [635d4f982a].
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | @property (readonly, nonatomic, getter=isCalculated) bool calculated; /** * @brief A buffer containing the cryptographic hash. * * The size of the buffer depends on the hash used. The buffer is part of the * receiver's memory pool. */ @property (readonly, nonatomic) const unsigned char *digest OF_RETURNS_INNER_POINTER; /** * @brief Creates a new cryptographic hash. * | > > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | @property (readonly, nonatomic, getter=isCalculated) bool calculated; /** * @brief A buffer containing the cryptographic hash. * * The size of the buffer depends on the hash used. The buffer is part of the * receiver's memory pool. * * @throw OFHashNotCalculatedException The hash hasn't been calculated yet */ @property (readonly, nonatomic) const unsigned char *digest OF_RETURNS_INNER_POINTER; /** * @brief Creates a new cryptographic hash. * |
︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | - (instancetype)init OF_UNAVAILABLE; /** * @brief Adds a buffer to the cryptographic hash to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; /** * @brief Performs the final calculation of the cryptographic hash. */ - (void)calculate; /** * @brief Resets all state so that a new hash can be calculated. * * @warning This invalidates any pointer previously returned by @ref digest. If | > > > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | - (instancetype)init OF_UNAVAILABLE; /** * @brief Adds a buffer to the cryptographic hash to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer * @throw OFHashAlreadyCalculatedException The hash has already been calculated */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; /** * @brief Performs the final calculation of the cryptographic hash. * * @throw OFHashAlreadyCalculatedException The hash has already been calculated */ - (void)calculate; /** * @brief Resets all state so that a new hash can be calculated. * * @warning This invalidates any pointer previously returned by @ref digest. If |
︙ | ︙ |
Added src/OFDDPSocket.h version [86e7a28476].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Copyright (c) 2008-2022 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 OFDDPSocketDelegate OFDDPSocket.h ObjFW/OFDDPSocket.h * * @brief A delegate for OFDDPSocket. */ @protocol OFDDPSocketDelegate <OFDatagramSocketDelegate> @end /** * @class OFDDPSocket OFDDPSocket.h ObjFW/OFDDPSocket.h * * @brief A class which provides methods to create and use AppleTalk DDP * sockets. * * Addresses are of type @ref OFSocketAddress. You can use * @ref OFSocketAddressMakeAppleTalk to create an address or * @ref OFSocketAddressAppleTalkNetwork to get the AppleTalk network, * @ref OFSocketAddressAppleTalkNode to get the AppleTalk node and * @ref OFSocketAddressAppleTalkPort to get the port (sometimes also called * socket number). * * @note On some systems, packets received with the wrong protocol type just * get filtered by the kernel, however, on other systems, the packet is * queued up and will raise an @ref OFReadFailedException with the * @ref errNo set to `ENOMSG` when being received. * * @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 OFDDPSocket: OFDatagramSocket { #if !defined(OF_MACOS) && !defined(OF_WINDOWS) uint8_t _protocolType; #endif OF_RESERVE_IVARS(OFDDPSocket, 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 <OFDDPSocketDelegate> delegate; /** * @brief Bind the socket to the specified network, node and port. * * @param network The network to bind to. 0 means any. * @param node The node to bind to. 0 means "this node". * @param port The port to bind to. 0 means to pick one and return it via the * returned socket address. * @param protocolType The DDP protocol type to use. Must not be 0. If you want * to use DDP directly and not a protocol built on top of * it, use 11 for compatibility with Open Transport. * @return The address on which this socket can be reached * @throw OFBindDDPSockeFailedException Binding failed * @throw OFAlreadyConnectedException The socket is already bound */ - (OFSocketAddress)bindToNetwork: (uint16_t)network node: (uint8_t)node port: (uint8_t)port protocolType: (uint8_t)protocolType; @end OF_ASSUME_NONNULL_END |
Added src/OFDDPSocket.m version [d532fdd70f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Copyright (c) 2008-2022 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 "OFDDPSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindDDPSocketFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifdef OF_HAVE_NETAT_APPLETALK_H # include <netat/ddp.h> # include <sys/ioctl.h> /* Unfortulately, there is no struct for the following in userland headers */ struct ATInterfaceConfig { char interfaceName[16]; unsigned int flags; struct at_addr address, router; unsigned short netStart, netEnd; at_nvestr_t zoneName; }; #endif @implementation OFDDPSocket @dynamic delegate; - (OFSocketAddress)bindToNetwork: (uint16_t)network node: (uint8_t)node port: (uint8_t)port protocolType: (uint8_t)protocolType { #ifdef OF_MACOS const int one = 1; struct ATInterfaceConfig config = { { 0 } }; #endif OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (protocolType == 0) @throw [OFInvalidArgumentException exception]; if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeAppleTalk(network, node, port); #if defined(OF_MACOS) if ((_socket = socket(address.sockaddr.at.sat_family, SOCK_RAW | SOCK_CLOEXEC, protocolType)) == OFInvalidSocketHandle) #elif defined(OF_WINDOWS) if ((_socket = socket(address.sockaddr.at.sat_family, SOCK_DGRAM | SOCK_CLOEXEC, ATPROTO_BASE + protocolType)) == OFInvalidSocketHandle) #else if ((_socket = socket(address.sockaddr.at.sat_family, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) #endif @throw [OFBindDDPSocketFailedException exceptionWithNetwork: network node: node port: port protocolType: protocolType socket: self errNo: OFSocketErrNo()]; _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, (struct sockaddr *)&address.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindDDPSocketFailedException exceptionWithNetwork: network node: node port: port protocolType: protocolType socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyAppleTalk; address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, (struct sockaddr *)&address.sockaddr, &address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindDDPSocketFailedException exceptionWithNetwork: network node: node port: port protocolType: protocolType socket: self errNo: errNo]; } if (address.sockaddr.at.sat_family != AF_APPLETALK) { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindDDPSocketFailedException exceptionWithNetwork: network node: node port: port protocolType: protocolType socket: self errNo: EAFNOSUPPORT]; } #ifdef OF_MACOS if (setsockopt(_socket, ATPROTO_NONE, DDP_STRIPHDR, &one, sizeof(one)) != 0 || ioctl(_socket, _IOWR('a', 2, struct ATInterfaceConfig), &config) != 0) @throw [OFBindDDPSocketFailedException exceptionWithNetwork: network node: node port: port protocolType: protocolType socket: self errNo: OFSocketErrNo()]; OFSocketAddressSetAppleTalkNetwork(&address, config.address.s_net); OFSocketAddressSetAppleTalkNode(&address, config.address.s_node); #endif #if !defined(OF_MACOS) && !defined(OF_WINDOWS) _protocolType = protocolType; #endif return address; } /* * Everybody but macOS and Windows is probably using a netatalk-compatible * implementation, which includes the protocol type as the first byte of the * data instead of considering it part of the header. * * The following overrides prepend the protocol type when sending and compare * and strip it when receiving. * * Unfortunately, the downside of this is that the only way to handle receiving * a packet with the wrong protocol type is to throw an exception with errNo * ENOMSG, while macOS and Windows just filter those out in the kernel. * Returning 0 would mean this is indistinguishable from an empty packet, so it * has to be an exception. */ #if !defined(OF_MACOS) && !defined(OF_WINDOWS) - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length sender: (OFSocketAddress *)sender { ssize_t ret; uint8_t protocolType; struct iovec iov[2] = { { &protocolType, 1 }, { buffer, length } }; struct msghdr msg = { .msg_name = (sender != NULL ? (struct sockaddr *)&sender->sockaddr : NULL), .msg_namelen = (sender != NULL ? (socklen_t)sizeof(sender->sockaddr) : 0), .msg_iov = iov, .msg_iovlen = 2 }; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if ((ret = recvmsg(_socket, &msg, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; if (ret < 1 || protocolType != _protocolType) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: ENOMSG]; if (sender != NULL) { sender->length = msg.msg_namelen; sender->family = OFSocketAddressFamilyAppleTalk; } return ret - 1; } - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const OFSocketAddress *)receiver { struct iovec iov[2] = { { &_protocolType, 1 }, { (void *)buffer, length } }; struct msghdr msg = { .msg_name = (struct sockaddr *)&receiver->sockaddr, .msg_namelen = receiver->length, .msg_iov = iov, .msg_iovlen = 2 }; ssize_t bytesWritten; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if ((bytesWritten = sendmsg(_socket, &msg, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; if ((size_t)bytesWritten != length + 1) { bytesWritten--; if (bytesWritten < 0) bytesWritten = 0; @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } } #endif @end |
Modified src/OFDNSQuery.h from [9c2a0f4bc6] to [b49f52a5a4].
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 | @class OFString; /** * @class OFDNSQuery OFDNSQuery.h ObjFW/OFDNSQuery.h * * @brief A class representing a DNS query. */ @interface OFDNSQuery: OFObject <OFCopying> { OFString *_domainName; OFDNSClass _DNSClass; OFDNSRecordType _recordType; | > < | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | @class OFString; /** * @class OFDNSQuery OFDNSQuery.h ObjFW/OFDNSQuery.h * * @brief A class representing a DNS query. */ OF_SUBCLASSING_RESTRICTED @interface OFDNSQuery: OFObject <OFCopying> { OFString *_domainName; OFDNSClass _DNSClass; OFDNSRecordType _recordType; } /** * @brief The domain name of the query. */ @property (readonly, nonatomic) OFString *domainName; |
︙ | ︙ |
Modified src/OFDNSQuery.m from [03ea4234b3] to [eb5858939c].
︙ | ︙ | |||
93 94 95 96 97 98 99 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _domainName.hash); | | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _domainName.hash); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType); OFHashFinalize(&hash); return hash; } - (id)copy { |
︙ | ︙ |
Modified src/OFDNSResolver.h from [0eee98275d] to [a91104c174].
︙ | ︙ | |||
256 257 258 259 260 261 262 263 264 265 266 267 268 269 | /** * @brief Synchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @return OFData containing several OFSocketAddress */ - (OFData *)resolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily; /** * @brief Closes all sockets and cancels all ongoing queries. */ | > > | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | /** * @brief Synchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @return OFData containing several OFSocketAddress * @throw OFInvalidServerResponseException The received response was invalid * @throw OFTruncatedDataException The received response was truncated */ - (OFData *)resolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily; /** * @brief Closes all sockets and cancels all ongoing queries. */ |
︙ | ︙ |
Modified src/OFDNSResolver.m from [6722a88381] to [9048cbfc52].
︙ | ︙ | |||
34 35 36 37 38 39 40 | #import "OFUDPSocket.h" #import "OFUDPSocket+Private.h" #import "OFDNSQueryFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #import "OFUDPSocket.h" #import "OFUDPSocket+Private.h" #import "OFDNSQueryFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerResponseException.h" #import "OFNotImplementedException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #ifndef SOCK_DNS # define SOCK_DNS 0 #endif |
︙ | ︙ | |||
124 125 126 127 128 129 130 | componentLength = buffer[(*i)++]; if (componentLength & 0xC0) { size_t j; OFString *suffix; if (pointerLevel == 0) | | | | 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 | componentLength = buffer[(*i)++]; if (componentLength & 0xC0) { size_t j; OFString *suffix; if (pointerLevel == 0) @throw [OFInvalidServerResponseException exception]; if (*i >= length) @throw [OFTruncatedDataException exception]; j = ((componentLength & 0x3F) << 8) | buffer[(*i)++]; if (j == *i - 2) /* Pointing to itself?! */ @throw [OFInvalidServerResponseException exception]; suffix = parseName(buffer, length, &j, pointerLevel - 1); if (components.count == 0) return suffix; |
︙ | ︙ | |||
171 172 173 174 175 176 177 | OFDNSRecordType recordType, uint32_t TTL, const unsigned char *buffer, size_t length, size_t i, uint16_t dataLength) { if (recordType == OFDNSRecordTypeA && DNSClass == OFDNSClassIN) { OFSocketAddress address; if (dataLength != 4) | | | | | | | 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 | OFDNSRecordType recordType, uint32_t TTL, const unsigned char *buffer, size_t length, size_t i, uint16_t dataLength) { if (recordType == OFDNSRecordTypeA && DNSClass == OFDNSClassIN) { OFSocketAddress address; if (dataLength != 4) @throw [OFInvalidServerResponseException exception]; memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPv4; address.length = sizeof(address.sockaddr.in); address.sockaddr.in.sin_family = AF_INET; memcpy(&address.sockaddr.in.sin_addr.s_addr, buffer + i, 4); return [[[OFADNSResourceRecord alloc] initWithName: name address: &address TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeNS) { size_t j = i; OFString *authoritativeHost = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFNSDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass authoritativeHost: authoritativeHost TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeCNAME) { size_t j = i; OFString *alias = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFCNAMEDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass alias: alias TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeSOA) { size_t j = i; OFString *primaryNameServer = parseName(buffer, length, &j, maxAllowedPointers); OFString *responsiblePerson; uint32_t serialNumber, refreshInterval, retryInterval; uint32_t expirationInterval, minTTL; if (j > i + dataLength) @throw [OFInvalidServerResponseException exception]; responsiblePerson = parseName(buffer, length, &j, maxAllowedPointers); if (dataLength - (j - i) != 20) @throw [OFInvalidServerResponseException exception]; serialNumber = (buffer[j] << 24) | (buffer[j + 1] << 16) | (buffer[j + 2] << 8) | buffer[j + 3]; refreshInterval = (buffer[j + 4] << 24) | (buffer[j + 5] << 16) | (buffer[j + 6] << 8) | buffer[j + 7]; retryInterval = (buffer[j + 8] << 24) | (buffer[j + 9] << 16) | |
︙ | ︙ | |||
257 258 259 260 261 262 263 | TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypePTR) { size_t j = i; OFString *domainName = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) | | | | | | | | 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 | TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypePTR) { size_t j = i; OFString *domainName = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFPTRDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass domainName: domainName TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeHINFO) { size_t j = i; OFString *CPU = parseString(buffer, length, &j); OFString *OS; if (j > i + dataLength) @throw [OFInvalidServerResponseException exception]; OS = parseString(buffer, length, &j); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFHINFODNSResourceRecord alloc] initWithName: name DNSClass: DNSClass CPU: CPU OS: OS TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeMX) { uint16_t preference; size_t j; OFString *mailExchange; if (dataLength < 2) @throw [OFInvalidServerResponseException exception]; preference = (buffer[i] << 8) | buffer[i + 1]; j = i + 2; mailExchange = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFMXDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass preference: preference mailExchange: mailExchange TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeTXT) { OFMutableArray *textStrings = [OFMutableArray array]; while (dataLength > 0) { uint_fast8_t stringLength = buffer[i++]; dataLength--; if (stringLength > dataLength) @throw [OFInvalidServerResponseException exception]; [textStrings addObject: [OFData dataWithItems: buffer + i count: stringLength]]; i += stringLength; |
︙ | ︙ | |||
339 340 341 342 343 344 345 | } else if (recordType == OFDNSRecordTypeRP) { size_t j = i; OFString *mailbox = parseName(buffer, length, &j, maxAllowedPointers); OFString *TXTDomainName; if (j > i + dataLength) | | | | | 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 | } else if (recordType == OFDNSRecordTypeRP) { size_t j = i; OFString *mailbox = parseName(buffer, length, &j, maxAllowedPointers); OFString *TXTDomainName; if (j > i + dataLength) @throw [OFInvalidServerResponseException exception]; TXTDomainName = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFRPDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass mailbox: mailbox TXTDomainName: TXTDomainName TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeAAAA && DNSClass == OFDNSClassIN) { OFSocketAddress address; if (dataLength != 16) @throw [OFInvalidServerResponseException exception]; memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPv6; address.length = sizeof(address.sockaddr.in6); #ifdef AF_INET6 address.sockaddr.in6.sin6_family = AF_INET6; |
︙ | ︙ | |||
382 383 384 385 386 387 388 | } else if (recordType == OFDNSRecordTypeSRV && DNSClass == OFDNSClassIN) { uint16_t priority, weight, port; size_t j; OFString *target; if (dataLength < 6) | | | | 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 | } else if (recordType == OFDNSRecordTypeSRV && DNSClass == OFDNSClassIN) { uint16_t priority, weight, port; size_t j; OFString *target; if (dataLength < 6) @throw [OFInvalidServerResponseException exception]; priority = (buffer[i] << 8) | buffer[i + 1]; weight = (buffer[i + 2] << 8) | buffer[i + 3]; port = (buffer[i + 4] << 8) | buffer[i + 5]; j = i + 6; target = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerResponseException exception]; return [[[OFSRVDNSResourceRecord alloc] initWithName: name priority: priority weight: weight target: target port: port |
︙ | ︙ | |||
906 907 908 909 910 911 912 | if (context == nil) return true; if (context->_TCPSocket != nil) { if ([_TCPQueries objectForKey: context->_TCPSocket] != context) return true; | > | | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 | if (context == nil) return true; if (context->_TCPSocket != nil) { if ([_TCPQueries objectForKey: context->_TCPSocket] != context) return true; } else if (sender == NULL || !OFSocketAddressEqual(sender, &context->_usedNameServer)) return true; [context->_cancelTimer invalidate]; [context->_cancelTimer release]; context->_cancelTimer = nil; [_queries removeObjectForKey: ID]; |
︙ | ︙ | |||
933 934 935 936 937 938 939 | context->_queryData.count < 12) @throw [OFInvalidArgumentException exception]; queryDataBuffer = context->_queryData.items; /* QR */ if ((buffer[2] & 0x80) == 0) | | | | 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 | context->_queryData.count < 12) @throw [OFInvalidArgumentException exception]; queryDataBuffer = context->_queryData.items; /* QR */ if ((buffer[2] & 0x80) == 0) @throw [OFInvalidServerResponseException exception]; /* Opcode */ if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78)) @throw [OFInvalidServerResponseException exception]; /* TC */ if (buffer[2] & 0x02) { OFRunLoopMode runLoopMode; if (context->_settings->_usesTCP) @throw [OFTruncatedDataException exception]; |
︙ | ︙ |
Modified src/OFDNSResolverSettings.m from [a43cd003ad] to [1a84838633].
︙ | ︙ | |||
178 179 180 181 182 183 184 | static OFArray OF_GENERIC(OFString *) * parseNetStackArray(OFString *string) { if (![string hasPrefix: @"["] || ![string hasSuffix: @"]"]) return nil; | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | static OFArray OF_GENERIC(OFString *) * parseNetStackArray(OFString *string) { if (![string hasPrefix: @"["] || ![string hasSuffix: @"]"]) return nil; string = [string substringWithRange: OFMakeRange(1, string.length - 2)]; return [string componentsSeparatedByString: @"|"]; } #endif @implementation OFDNSResolverSettings - (void)dealloc |
︙ | ︙ | |||
264 265 266 267 268 269 270 | } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } staticHosts = [OFMutableDictionary dictionary]; | | > | | 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 | } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } staticHosts = [OFMutableDictionary dictionary]; while ((line = [file readLineWithEncoding: [OFLocale encoding]]) != nil) { OFArray *components, *hosts; size_t pos; OFString *address; pos = [line rangeOfString: @"#"].location; if (pos != OFNotFound) line = [line substringToIndex: pos]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OFStringSkipEmptyComponents]; if (components.count < 2) continue; address = components.firstObject; hosts = [components objectsInRange: OFMakeRange(1, components.count - 1)]; for (OFString *host in hosts) { OFMutableArray *addresses = [staticHosts objectForKey: host]; if (addresses == nil) { addresses = [OFMutableArray array]; |
︙ | ︙ | |||
364 365 366 367 368 369 370 | objc_autoreleasePoolPop(pool); return; } if (nameServers == nil) nameServers = [OFMutableArray array]; | | > | | 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 | objc_autoreleasePoolPop(pool); return; } if (nameServers == nil) nameServers = [OFMutableArray array]; while ((line = [file readLineWithEncoding: [OFLocale encoding]]) != nil) { void *pool2 = objc_autoreleasePoolPush(); size_t pos; OFArray *components, *arguments; OFString *option; pos = [line indexOfCharacterFromSet: commentCharacters]; if (pos != OFNotFound) line = [line substringToIndex: pos]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OFStringSkipEmptyComponents]; if (components.count < 2) { objc_autoreleasePoolPop(pool2); continue; } option = components.firstObject; arguments = [components objectsInRange: OFMakeRange(1, components.count - 1)]; if ([option isEqual: @"nameserver"]) { if (arguments.count != 1) { objc_autoreleasePoolPop(pool2); continue; } |
︙ | ︙ | |||
484 485 486 487 488 489 490 | OFArray *hosts; if (components.count < 2) continue; address = components.firstObject; hosts = [components objectsInRange: | | | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | OFArray *hosts; if (components.count < 2) continue; address = components.firstObject; hosts = [components objectsInRange: OFMakeRange(1, components.count - 1)]; for (OFString *host in hosts) { OFMutableArray *addresses = [staticHosts objectForKey: host]; if (addresses == nil) { addresses = [OFMutableArray array]; |
︙ | ︙ | |||
619 620 621 622 623 624 625 | [self setDefaults]; #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES OFWindowsRegistryKey *key = [[OFWindowsRegistryKey localMachineKey] openSubkeyAtPath: @"SYSTEM\\CurrentControlSet\\Services\\" @"Tcpip\\Parameters" | | > | 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | [self setDefaults]; #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES OFWindowsRegistryKey *key = [[OFWindowsRegistryKey localMachineKey] openSubkeyAtPath: @"SYSTEM\\CurrentControlSet\\Services\\" @"Tcpip\\Parameters" accessRights: KEY_QUERY_VALUE options: 0]; path = [[[key stringForValueNamed: @"DataBasePath"] stringByAppendingPathComponent: @"hosts"] stringByExpandingWindowsEnvironmentStrings]; if (path != nil) [self parseHosts: path]; # endif |
︙ | ︙ |
Modified src/OFDNSResourceRecord.h from [1c8f2631a7] to [30273f1f1b].
︙ | ︙ | |||
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 | extern OFString *_Nonnull OFDNSRecordTypeName(OFDNSRecordType recordType); /** * @brief Parses the specified string as an @ref OFDNSClass. * * @param string The string to parse as an @ref OFDNSClass * @return The parsed OFDNSClass */ extern OFDNSClass OFDNSClassParseName(OFString *_Nonnull string); /** * @brief Parses the specified string as an @ref OFDNSRecordType. * * @param string The string to parse as an @ref OFDNSRecordType * @return The parsed OFDNSRecordType */ extern OFDNSRecordType OFDNSRecordTypeParseName(OFString *_Nonnull string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END | > > | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | extern OFString *_Nonnull OFDNSRecordTypeName(OFDNSRecordType recordType); /** * @brief Parses the specified string as an @ref OFDNSClass. * * @param string The string to parse as an @ref OFDNSClass * @return The parsed OFDNSClass * @throw OFInvalidFormatException The specified string is not valid DNS class */ extern OFDNSClass OFDNSClassParseName(OFString *_Nonnull string); /** * @brief Parses the specified string as an @ref OFDNSRecordType. * * @param string The string to parse as an @ref OFDNSRecordType * @return The parsed OFDNSRecordType * @throw OFInvalidFormatException The specified string is not valid DNS class */ extern OFDNSRecordType OFDNSRecordTypeParseName(OFString *_Nonnull string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFDNSResourceRecord.m from [5aceee5a6c] to [b7ec251a31].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "config.h" #import "OFDNSResourceRecord.h" #import "OFArray.h" #import "OFData.h" | < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include "config.h" #import "OFDNSResourceRecord.h" #import "OFArray.h" #import "OFData.h" #import "OFInvalidFormatException.h" OFString * OFDNSClassName(OFDNSClass DNSClass) { switch (DNSClass) { case OFDNSClassIN: |
︙ | ︙ | |||
75 76 77 78 79 80 81 | OFDNSClass DNSClass; string = string.uppercaseString; if ([string isEqual: @"IN"]) DNSClass = OFDNSClassIN; else { | < | | < < < | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | OFDNSClass DNSClass; string = string.uppercaseString; if ([string isEqual: @"IN"]) DNSClass = OFDNSClassIN; else { DNSClass = (OFDNSClass)[string unsignedLongLongValueWithBase: 0]; } objc_autoreleasePoolPop(pool); return DNSClass; } |
︙ | ︙ | |||
121 122 123 124 125 126 127 | else if ([string isEqual: @"AAAA"]) recordType = OFDNSRecordTypeAAAA; else if ([string isEqual: @"SRV"]) recordType = OFDNSRecordTypeSRV; else if ([string isEqual: @"ALL"]) recordType = OFDNSRecordTypeAll; else { | < | | < < < | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | else if ([string isEqual: @"AAAA"]) recordType = OFDNSRecordTypeAAAA; else if ([string isEqual: @"SRV"]) recordType = OFDNSRecordTypeSRV; else if ([string isEqual: @"ALL"]) recordType = OFDNSRecordTypeAll; else { recordType = (OFDNSRecordType)[string unsignedLongLongValueWithBase: 0]; } objc_autoreleasePoolPop(pool); return recordType; } |
︙ | ︙ | |||
246 247 248 249 250 251 252 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, OFSocketAddressHash(&_address)); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
331 332 333 334 335 336 337 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, OFSocketAddressHash(&_address)); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
426 427 428 429 430 431 432 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _alias.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
528 529 530 531 532 533 534 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _CPU.hash); OFHashAddHash(&hash, _OS.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
632 633 634 635 636 637 638 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | | | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddByte(&hash, _preference >> 8); OFHashAddByte(&hash, _preference); OFHashAddHash(&hash, _mailExchange.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
733 734 735 736 737 738 739 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _authoritativeHost.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
831 832 833 834 835 836 837 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _domainName.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
936 937 938 939 940 941 942 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _mailbox.hash); OFHashAddHash(&hash, _TXTDomainName.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _primaryNameServer.hash); OFHashAddHash(&hash, _responsiblePerson.hash); OFHashAddByte(&hash, _serialNumber >> 24); OFHashAddByte(&hash, _serialNumber >> 16); OFHashAddByte(&hash, _serialNumber >> 8); OFHashAddByte(&hash, _serialNumber); OFHashAddByte(&hash, _refreshInterval >> 24); OFHashAddByte(&hash, _refreshInterval >> 16); OFHashAddByte(&hash, _refreshInterval >> 8); OFHashAddByte(&hash, _refreshInterval); OFHashAddByte(&hash, _retryInterval >> 24); OFHashAddByte(&hash, _retryInterval >> 16); OFHashAddByte(&hash, _retryInterval >> 8); OFHashAddByte(&hash, _retryInterval); OFHashAddByte(&hash, _expirationInterval >> 24); OFHashAddByte(&hash, _expirationInterval >> 16); OFHashAddByte(&hash, _expirationInterval >> 8); OFHashAddByte(&hash, _expirationInterval); OFHashAddByte(&hash, _minTTL >> 24); OFHashAddByte(&hash, _minTTL >> 16); OFHashAddByte(&hash, _minTTL >> 8); OFHashAddByte(&hash, _minTTL); OFHashFinalize(&hash); return hash; } - (OFString *)description |
︙ | ︙ | |||
1213 1214 1215 1216 1217 1218 1219 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | | | | | | | 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 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddByte(&hash, _priority >> 8); OFHashAddByte(&hash, _priority); OFHashAddByte(&hash, _weight >> 8); OFHashAddByte(&hash, _weight); OFHashAddHash(&hash, _target.hash); OFHashAddByte(&hash, _port >> 8); OFHashAddByte(&hash, _port); OFHashFinalize(&hash); return hash; } - (OFString *)description |
︙ | ︙ | |||
1318 1319 1320 1321 1322 1323 1324 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); | | | | | | 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddByte(&hash, _DNSClass >> 8); OFHashAddByte(&hash, _DNSClass); OFHashAddByte(&hash, _recordType >> 8); OFHashAddByte(&hash, _recordType); OFHashAddHash(&hash, _textStrings.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ |
Modified src/OFDNSResponse.h from [12d5300b31] to [229f42ebfc].
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 | OF_KINDOF(OFDNSResourceRecord *)) *) *OFDNSResponseRecords; /** * @class OFDNSResponse OFDNSResponse.h ObjFW/OFDNSResponse.h * * @brief A class storing a response from @ref OFDNSResolver. */ @interface OFDNSResponse: OFObject { OFString *_domainName; OFDNSResponseRecords _answerRecords, _authorityRecords; OFDNSResponseRecords _additionalRecords; | > < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | OF_KINDOF(OFDNSResourceRecord *)) *) *OFDNSResponseRecords; /** * @class OFDNSResponse OFDNSResponse.h ObjFW/OFDNSResponse.h * * @brief A class storing a response from @ref OFDNSResolver. */ OF_SUBCLASSING_RESTRICTED @interface OFDNSResponse: OFObject { OFString *_domainName; OFDNSResponseRecords _answerRecords, _authorityRecords; OFDNSResponseRecords _additionalRecords; } /** * @brief The domain name of the response. */ @property (readonly, nonatomic) OFString *domainName; |
︙ | ︙ |
Modified src/OFData+ASN1DERParsing.m from [fa73f4a2f7] to [515019e2e6].
︙ | ︙ | |||
57 58 59 60 61 62 63 | id object; size_t objectLength; objectLength = parseObject(contents, &object, depthLimit); count -= objectLength; contents = [contents subdataWithRange: | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | id object; size_t objectLength; objectLength = parseObject(contents, &object, depthLimit); count -= objectLength; contents = [contents subdataWithRange: OFMakeRange(objectLength, count)]; [ret addObject: object]; } [ret makeImmutable]; return ret; |
︙ | ︙ | |||
84 85 86 87 88 89 90 | while (count > 0) { id object; size_t objectLength; OFData *objectData; objectLength = parseObject(contents, &object, depthLimit); objectData = [contents subdataWithRange: | | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | while (count > 0) { id object; size_t objectLength; OFData *objectData; objectLength = parseObject(contents, &object, depthLimit); objectData = [contents subdataWithRange: OFMakeRange(0, objectLength)]; if (previousObjectData != nil && [objectData compare: previousObjectData] != OFOrderedDescending) @throw [OFInvalidFormatException exception]; count -= objectLength; contents = [contents subdataWithRange: OFMakeRange(objectLength, count)]; [ret addObject: object]; previousObjectData = objectData; } [ret makeImmutable]; |
︙ | ︙ | |||
151 152 153 154 155 156 157 | @throw [OFInvalidFormatException exception]; } if (count - bytesConsumed < contentsLength) @throw [OFTruncatedDataException exception]; contents = [self subdataWithRange: | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | @throw [OFInvalidFormatException exception]; } if (count - bytesConsumed < contentsLength) @throw [OFTruncatedDataException exception]; contents = [self subdataWithRange: OFMakeRange(bytesConsumed, contentsLength)]; bytesConsumed += contentsLength; switch (tag & ~tagConstructedMask) { case OFASN1TagNumberBoolean: valueClass = [OFASN1Boolean class]; break; case OFASN1TagNumberInteger: |
︙ | ︙ |
Modified src/OFData+MessagePackParsing.h from [38e581e80e] to [1a7c410992].
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | } #endif @interface OFData (MessagePackParsing) /** * @brief The data interpreted as MessagePack representation and parsed as an * object. */ @property (readonly, nonatomic) id objectByParsingMessagePack; /** * @brief Parses the MessagePack representation and returns it as an object. * * @param depthLimit The maximum depth the parser should accept (defaults to 32 * if not specified, 0 means no limit (insecure!)) * @return The MessagePack representation as an object */ - (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit; @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > | 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 | } #endif @interface OFData (MessagePackParsing) /** * @brief The data interpreted as MessagePack representation and parsed as an * object. * * @throw OFInvalidFormatException The MessagePack representation contained in * the data contained an invalid format * @throw OFTruncatedDataException The MessagePack representation contained in * the data is truncated * @throw OFOutOfRangeException The depth limit has been exceeded */ @property (readonly, nonatomic) id objectByParsingMessagePack; /** * @brief Parses the MessagePack representation and returns it as an object. * * @param depthLimit The maximum depth the parser should accept (defaults to 32 * if not specified, 0 means no limit (insecure!)) * @return The MessagePack representation as an object * @throw OFInvalidFormatException The MessagePack representation contained in * the data contained an invalid format * @throw OFTruncatedDataException The MessagePack representation contained in * the data is truncated * @throw OFOutOfRangeException The depth limit has been exceeded */ - (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit; @end OF_ASSUME_NONNULL_END |
Modified src/OFData.h from [78a81eb330] to [b5feba23f0].
︙ | ︙ | |||
18 19 20 21 22 23 24 | #import "OFMessagePackRepresentation.h" /*! @file */ OF_ASSUME_NONNULL_BEGIN @class OFString; | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #import "OFMessagePackRepresentation.h" /*! @file */ OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFURI; /** * @brief Options for searching in data. * * This is a bit mask. */ typedef enum { |
︙ | ︙ | |||
163 164 165 166 167 168 169 | * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfFile: (OFString *)path; #endif /** * @brief Creates a new OFData with an item size of 1, containing the data of | | | | > > > > | 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 | * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfFile: (OFString *)path; #endif /** * @brief Creates a new OFData with an item size of 1, containing the data of * the specified URI. * * @param URI The URI to the contents for the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfURI: (OFURI *)URI; /** * @brief Creates a new OFData with an item size of 1, containing the data of * the hex string representation. * * @param string The hex string representation of the data * @return A new autoreleased OFData * @throw OFInvalidFormatException The specified string is not correctly * formatted */ + (instancetype)dataWithStringRepresentation: (OFString *)string; /** * @brief Creates a new OFData with an item size of 1, containing the data of * the Base64-encoded string. * * @param string The string with the Base64-encoded data * @return A new autoreleased OFData * @throw OFInvalidFormatException The specified string is not correctly * formatted */ + (instancetype)dataWithBase64EncodedString: (OFString *)string; /** * @brief Initializes an already allocated OFData with the specified `count` * items of size 1. * |
︙ | ︙ | |||
262 263 264 265 266 267 268 | * @return An initialized OFData */ - (instancetype)initWithContentsOfFile: (OFString *)path; #endif /** * @brief Initializes an already allocated OFData with an item size of 1, | | | | > > > > | 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 | * @return An initialized OFData */ - (instancetype)initWithContentsOfFile: (OFString *)path; #endif /** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the specified URI. * * @param URI The URI to the contents for the OFData * @return A new autoreleased OFData */ - (instancetype)initWithContentsOfURI: (OFURI *)URI; /** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the hex string representation. * * @param string The hex string representation of the data * @return A new autoreleased OFData * @throw OFInvalidFormatException The specified string is not correctly * formatted */ - (instancetype)initWithStringRepresentation: (OFString *)string; /** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the Base64-encoded string. * * @param string The string with the Base64-encoded data * @return An initialized OFData * @throw OFInvalidFormatException The specified string is not correctly * formatted */ - (instancetype)initWithBase64EncodedString: (OFString *)string; /** * @brief Compares the data to other data. * * @param data Data to compare the data to |
︙ | ︙ | |||
334 335 336 337 338 339 340 | * * @param path The path of the file to write to */ - (void)writeToFile: (OFString *)path; #endif /** | | | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | * * @param path The path of the file to write to */ - (void)writeToFile: (OFString *)path; #endif /** * @brief Writes the OFData to the specified URI. * * @param URI The URI to write to */ - (void)writeToURI: (OFURI *)URI; @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" #import "OFData+ASN1DERParsing.h" #import "OFData+CryptographicHashing.h" #import "OFData+MessagePackParsing.h" |
Modified src/OFData.m from [2ce5037425] to [7f49d598ed].
︙ | ︙ | |||
25 26 27 28 29 30 31 | #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFStream.h" #import "OFString.h" #import "OFSystemInfo.h" | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFStream.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFURI.h" #import "OFURIHandler.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" /* References for static linking */ void |
︙ | ︙ | |||
90 91 92 93 94 95 96 | #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path { return [[[self alloc] initWithContentsOfFile: path] autorelease]; } #endif | | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path { return [[[self alloc] initWithContentsOfFile: path] autorelease]; } #endif + (instancetype)dataWithContentsOfURI: (OFURI *)URI { return [[[self alloc] initWithContentsOfURI: URI] autorelease]; } + (instancetype)dataWithStringRepresentation: (OFString *)string { return [[[self alloc] initWithStringRepresentation: string] autorelease]; } |
︙ | ︙ | |||
172 173 174 175 176 177 178 | return self; } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { char *buffer = NULL; | | > | | < < < | | > | < < | < < | > | | < | < < < < < < | 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 | return self; } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { char *buffer = NULL; OFStreamOffset fileSize; @try { void *pool = objc_autoreleasePoolPush(); OFFile *file = [OFFile fileWithPath: path mode: @"r"]; fileSize = [file seekToOffset: 0 whence: OFSeekEnd]; if (fileSize < 0 || (unsigned long long)fileSize > SIZE_MAX) @throw [OFOutOfRangeException exception]; [file seekToOffset: 0 whence: OFSeekSet]; buffer = OFAllocMemory((size_t)fileSize, 1); [file readIntoBuffer: buffer exactLength: (size_t)fileSize]; objc_autoreleasePoolPop(pool); } @catch (id e) { OFFreeMemory(buffer); [self release]; @throw e; } @try { self = [self initWithItemsNoCopy: buffer count: (size_t)fileSize freeWhenDone: true]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return self; } #endif - (instancetype)initWithContentsOfURI: (OFURI *)URI { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFStream *stream = [OFURIHandler openItemAtURI: URI mode: @"r"]; size_t pageSize; unsigned char *buffer; _count = 0; _itemSize = 1; _freeWhenDone = true; pageSize = [OFSystemInfo pageSize]; buffer = OFAllocMemory(1, pageSize); |
︙ | ︙ | |||
481 482 483 484 485 486 487 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < _count * _itemSize; i++) | | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < _count * _itemSize; i++) OFHashAddByte(&hash, ((uint8_t *)_items)[i]); OFHashFinalize(&hash); return hash; } - (OFData *)subdataWithRange: (OFRange)range |
︙ | ︙ | |||
555 556 557 558 559 560 561 | range.location + range.length > _count) @throw [OFOutOfRangeException exception]; if (data == nil || data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; if ((searchLength = data.count) == 0) | | | | | | | < < < < | | > | > | 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 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | range.location + range.length > _count) @throw [OFOutOfRangeException exception]; if (data == nil || data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; if ((searchLength = data.count) == 0) return OFMakeRange(0, 0); if (searchLength > range.length) return OFMakeRange(OFNotFound, 0); search = data.items; if (options & OFDataSearchBackwards) { for (size_t i = range.length - searchLength;; i--) { if (memcmp(_items + i * _itemSize, search, searchLength * _itemSize) == 0) return OFMakeRange(i, searchLength); /* No match and we're at the last item */ if (i == 0) break; } } else { for (size_t i = range.location; i <= range.length - searchLength; i++) if (memcmp(_items + i * _itemSize, search, searchLength * _itemSize) == 0) return OFMakeRange(i, searchLength); } return OFMakeRange(OFNotFound, 0); } #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { OFFile *file = [[OFFile alloc] initWithPath: path mode: @"w"]; @try { [file writeBuffer: _items length: _count * _itemSize]; } @finally { [file release]; } } #endif - (void)writeToURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); [[OFURIHandler openItemAtURI: URI mode: @"w"] writeData: self]; objc_autoreleasePoolPop(pool); } - (OFXMLElement *)XMLElementBySerializing { void *pool; OFXMLElement *element; if (_itemSize != 1) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; pool = objc_autoreleasePoolPush(); element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: OFBase64Encode(_items, _count * _itemSize)]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFData *)messagePackRepresentation { OFMutableData *data; if (_itemSize != 1) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (_count <= UINT8_MAX) { uint8_t type = 0xC4; uint8_t tmp = (uint8_t)_count; data = [OFMutableData dataWithCapacity: _count + 2]; [data addItem: &type]; |
︙ | ︙ |
Modified src/OFDatagramSocket.h from [c9d6b20376] to [81b28eb069].
︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | OF_RESERVE_IVARS(OFDatagramSocket, 4) } /** * @brief Whether the socket can block. * * By default, a socket can block. */ @property (nonatomic) bool canBlock; /** * @brief Whether the socket can send to broadcast addresses. */ @property (nonatomic) bool canSendToBroadcastAddresses; /** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are | > > > > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | OF_RESERVE_IVARS(OFDatagramSocket, 4) } /** * @brief Whether the socket can block. * * By default, a socket can block. * * @throw OFSetOptionFailedException The option could not be set */ @property (nonatomic) bool canBlock; /** * @brief Whether the socket can send to broadcast addresses. * * @throw OFSetOptionFailedException The option could not be set */ @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 |
︙ | ︙ | |||
147 148 149 150 151 152 153 154 155 156 | * 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 OFSocketAddress, 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 | > > | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | * 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 OFSocketAddress, which will be set to the * address of the sender * @return The length of the received datagram * @throw OFReadFailedException Receiving failed * @throw OFNotOpenException The socket is not open */ - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length sender: (nullable OFSocketAddress *)sender; /** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * |
︙ | ︙ | |||
226 227 228 229 230 231 232 233 234 235 236 237 238 239 | /** * @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 OFSocketAddress to which the datagram * should be sent */ - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const OFSocketAddress *)receiver; /** * @brief Asynchronously sends the specified datagram to the specified address. | > > | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | /** * @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 OFSocketAddress to which the datagram * should be sent * @throw OFWriteFailedException Sending failed * @throw OFNotOpenException The socket is not open */ - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const OFSocketAddress *)receiver; /** * @brief Asynchronously sends the specified datagram to the specified address. |
︙ | ︙ | |||
293 294 295 296 297 298 299 300 301 302 303 304 | * @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 | > > | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | * @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. * * @throw OFNotOpenException The socket is not open */ - (void)close; @end OF_ASSUME_NONNULL_END |
Modified src/OFDatagramSocket.m from [bbb2f277d7] to [ea19c6b109].
︙ | ︙ | |||
169 170 171 172 173 174 175 | sender: (OFSocketAddress *)sender { ssize_t ret; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; | > | | > | > > | | | | | | | | | | | | | > > > > > | | | > | 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 | sender: (OFSocketAddress *)sender { ssize_t ret; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (sender != NULL) sender->length = (socklen_t)sizeof(sender->sockaddr); #ifndef OF_WINDOWS if ((ret = recvfrom(_socket, buffer, length, 0, (sender != NULL ? (struct sockaddr *)&sender->sockaddr : NULL), (sender != NULL ? &sender->length : NULL))) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recvfrom(_socket, buffer, (int)length, 0, (sender != NULL ? (struct sockaddr *)&sender->sockaddr : NULL), (sender != NULL ? &sender->length : NULL))) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #endif if (sender != NULL) { switch (((struct sockaddr *)&sender->sockaddr)->sa_family) { case AF_INET: sender->family = OFSocketAddressFamilyIPv4; break; #ifdef OF_HAVE_IPV6 case AF_INET6: sender->family = OFSocketAddressFamilyIPv6; break; #endif #ifdef OF_HAVE_UNIX_SOCKETS case AF_UNIX: sender->family = OFSocketAddressFamilyUNIX; break; #endif #ifdef OF_HAVE_IPX case AF_IPX: sender->family = OFSocketAddressFamilyIPX; break; #endif #ifdef OF_HAVE_APPLETALK case AF_APPLETALK: sender->family = OFSocketAddressFamilyAppleTalk; break; #endif default: sender->family = OFSocketAddressFamilyUnknown; break; } } return ret; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length { |
︙ | ︙ |
Modified src/OFDate.h from [f33ded2414] to [ba59d767f1].
︙ | ︙ | |||
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 | * @warning The format is currently limited to the following format specifiers: * %%a, %%b, %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%z, %%, %%n and * %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithDateString: (OFString *)string format: (OFString *)format; /** * @brief Creates a new OFDate with the specified string in the specified * format. * * See the man page for `strftime` for information on the format. * * @warning The format is currently limited to the following format specifiers: * %%a, %%b, %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%z, %%, %%n and * %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithLocalDateString: (OFString *)string format: (OFString *)format; /** * @brief Returns a date in the distant future. * | > > | 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 | * @warning The format is currently limited to the following format specifiers: * %%a, %%b, %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%z, %%, %%n and * %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return A new, autoreleased OFDate with the specified date and time * @throw OFInvalidFormatException The specified format is invalid */ + (instancetype)dateWithDateString: (OFString *)string format: (OFString *)format; /** * @brief Creates a new OFDate with the specified string in the specified * format. * * See the man page for `strftime` for information on the format. * * @warning The format is currently limited to the following format specifiers: * %%a, %%b, %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%z, %%, %%n and * %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return A new, autoreleased OFDate with the specified date and time * @throw OFInvalidFormatException The specified format is invalid */ + (instancetype)dateWithLocalDateString: (OFString *)string format: (OFString *)format; /** * @brief Returns a date in the distant future. * |
︙ | ︙ | |||
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 | * * @warning The format is currently limited to the following format specifiers: * %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%, %%n and %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format; /** * @brief Initializes an already allocated OFDate with the specified string in * the specified format. * * If no time zone is specified, local time is assumed. * * See the man page for `strftime` for information on the format. * * @warning The format is currently limited to the following format specifiers: * %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%, %%n and %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format; /** * @brief Compares the date to another date. * * @param date The date to compare the date to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFDate *)date; /** * @brief Creates a string of the date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString */ - (OFString *)dateStringWithFormat: (OFConstantString *)format; /** * @brief Creates a string of the local date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString */ - (OFString *)localDateStringWithFormat: (OFConstantString *)format; /** * @brief Returns the earlier of the two dates. * * If the argument is `nil`, it returns the receiver. | > > > > | 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 | * * @warning The format is currently limited to the following format specifiers: * %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%, %%n and %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return An initialized OFDate with the specified date and time * @throw OFInvalidFormatException The specified format is invalid */ - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format; /** * @brief Initializes an already allocated OFDate with the specified string in * the specified format. * * If no time zone is specified, local time is assumed. * * See the man page for `strftime` for information on the format. * * @warning The format is currently limited to the following format specifiers: * %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%, %%n and %%t. * * @param string The string describing the date * @param format The format of the string describing the date * @return An initialized OFDate with the specified date and time * @throw OFInvalidFormatException The specified format is invalid */ - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format; /** * @brief Compares the date to another date. * * @param date The date to compare the date to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFDate *)date; /** * @brief Creates a string of the date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString * @throw OFInvalidFormatException The specified format is invalid */ - (OFString *)dateStringWithFormat: (OFConstantString *)format; /** * @brief Creates a string of the local date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString * @throw OFInvalidFormatException The specified format is invalid */ - (OFString *)localDateStringWithFormat: (OFConstantString *)format; /** * @brief Returns the earlier of the two dates. * * If the argument is `nil`, it returns the receiver. |
︙ | ︙ |
Modified src/OFDate.m from [ebc414dd12] to [692871b1cf].
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #import "OFMessagePackExtension.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFStrPTime.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFMessagePackExtension.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFStrPTime.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" |
︙ | ︙ | |||
502 503 504 505 506 507 508 509 510 511 512 513 514 515 | @try { void *pool = objc_autoreleasePoolPush(); unsigned long long value; if (![element.name isEqual: @"OFDate"] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; value = [element unsignedLongLongValueWithBase: 16]; if (value > UINT64_MAX) @throw [OFOutOfRangeException exception]; seconds = OFFromBigEndianDouble(OFRawUInt64ToDouble( | > > > > | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | @try { void *pool = objc_autoreleasePoolPush(); unsigned long long value; if (![element.name isEqual: @"OFDate"] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; if (![[element attributeForName: @"encoding"].stringValue isEqual: @"hex"]) @throw [OFInvalidFormatException exception]; value = [element unsignedLongLongValueWithBase: 16]; if (value > UINT64_MAX) @throw [OFOutOfRangeException exception]; seconds = OFFromBigEndianDouble(OFRawUInt64ToDouble( |
︙ | ︙ | |||
548 549 550 551 552 553 554 | double tmp; OFHashInit(&hash); tmp = OFToLittleEndianDouble(self.timeIntervalSince1970); for (size_t i = 0; i < sizeof(double); i++) | | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | double tmp; OFHashInit(&hash); tmp = OFToLittleEndianDouble(self.timeIntervalSince1970); for (size_t i = 0; i < sizeof(double); i++) OFHashAddByte(&hash, ((char *)&tmp)[i]); OFHashFinalize(&hash); return hash; } - (id)copy |
︙ | ︙ | |||
586 587 588 589 590 591 592 593 594 595 596 597 598 599 | { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFDate" namespace: OFSerializationNS]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OFFromBigEndian64(OFDoubleToRawUInt64(OFToBigEndianDouble( self.timeIntervalSince1970)))]; [element retain]; objc_autoreleasePoolPop(pool); | > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFDate" namespace: OFSerializationNS]; [element addAttributeWithName: @"encoding" stringValue: @"hex"]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OFFromBigEndian64(OFDoubleToRawUInt64(OFToBigEndianDouble( self.timeIntervalSince1970)))]; [element retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified src/OFDictionary.h from [a605581e45] to [73af2a9ef3].
︙ | ︙ | |||
89 90 91 92 93 94 95 | @property (readonly, nonatomic) OFArray OF_GENERIC(KeyType) *allKeys; /** * @brief An array of all objects. */ @property (readonly, nonatomic) OFArray OF_GENERIC(ObjectType) *allObjects; | < < < < < | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | @property (readonly, nonatomic) OFArray OF_GENERIC(KeyType) *allKeys; /** * @brief An array of all objects. */ @property (readonly, nonatomic) OFArray OF_GENERIC(ObjectType) *allObjects; /** * @brief Creates a new OFDictionary. * * @return A new autoreleased OFDictionary */ + (instancetype)dictionary; |
︙ | ︙ | |||
243 244 245 246 247 248 249 | * @return The value for the given key or `nil` if the key was not found */ - (nullable id)valueForKey: (OFString *)key; /** * @brief Sets a value for a key. * | | < > | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | * @return The value for the given key or `nil` if the key was not found */ - (nullable id)valueForKey: (OFString *)key; /** * @brief Sets a value for a key. * * This is equivalent to OFMutableDictionary#setObject:forKey:. * * @param key The key to set * @param value The value to set the key to * @throw OFUndefinedKeyException The dictionary is immutable */ - (void)setValue: (nullable id)value forKey: (OFString *)key; /** * @brief Checks whether the dictionary contains an object equal to the * specified object. * |
︙ | ︙ |
Modified src/OFDictionary.m from [a48510c034] to [9689ae0f89].
︙ | ︙ | |||
32 33 34 35 36 37 38 | #import "OFOutOfRangeException.h" #import "OFUndefinedKeyException.h" static struct { Class isa; } placeholder; | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #import "OFOutOfRangeException.h" #import "OFUndefinedKeyException.h" static struct { Class isa; } placeholder; static OFCharacterSet *URIQueryPartAllowedCharacterSet = nil; @interface OFDictionary () - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth; @end |
︙ | ︙ | |||
54 55 56 57 58 59 60 | OFEnumerator *_keyEnumerator; } - (instancetype)initWithDictionary: (OFDictionary *)dictionary; @end OF_DIRECT_MEMBERS | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | OFEnumerator *_keyEnumerator; } - (instancetype)initWithDictionary: (OFDictionary *)dictionary; @end OF_DIRECT_MEMBERS @interface OFURIQueryPartAllowedCharacterSet: OFCharacterSet + (OFCharacterSet *)URIQueryPartAllowedCharacterSet; @end @implementation OFDictionaryPlaceholder - (instancetype)init { return (id)[[OFMapTableDictionary alloc] init]; } |
︙ | ︙ | |||
137 138 139 140 141 142 143 | - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end | | | | | | | | 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 | - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end @implementation OFURIQueryPartAllowedCharacterSet + (void)initialize { if (self != [OFURIQueryPartAllowedCharacterSet class]) return; URIQueryPartAllowedCharacterSet = [[OFURIQueryPartAllowedCharacterSet alloc] init]; } + (OFCharacterSet *)URIQueryPartAllowedCharacterSet { return URIQueryPartAllowedCharacterSet; } - (instancetype)autorelease { return self; } |
︙ | ︙ | |||
628 629 630 631 632 633 634 | [ret appendString: @";\n"]; objc_autoreleasePoolPop(pool2); } [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @";\n}"]; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 628 629 630 631 632 633 634 635 636 637 638 639 640 641 | [ret appendString: @";\n"]; objc_autoreleasePoolPop(pool2); } [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @";\n}"]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } |
︙ | ︙ |
Renamed and modified src/OFEmbeddedFileURLHandler.h [b889d68d61] to src/OFEmbeddedURIHandler.h [5163464dd8].
︙ | ︙ | |||
9 10 11 12 13 14 15 | * * 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. */ | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * * 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 "OFURIHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFEmbeddedURIHandler: OFURIHandler @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFEmbeddedFileURLHandler.m [10ad5c2607] to src/OFEmbeddedURIHandler.m [bac2da914b].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "config.h" #include <errno.h> #include <stdlib.h> #include <string.h> | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include "config.h" #include <errno.h> #include <stdlib.h> #include <string.h> #import "OFEmbeddedURIHandler.h" #import "OFMemoryStream.h" #import "OFURI.h" #import "OFInvalidArgumentException.h" #import "OFOpenItemFailedException.h" #ifdef OF_HAVE_THREADS # import "OFOnce.h" # import "OFPlainMutex.h" |
︙ | ︙ | |||
67 68 69 70 71 72 73 | numEmbeddedFiles++; #ifdef OF_HAVE_THREADS OFEnsure(OFPlainMutexUnlock(&mutex) == 0); #endif } | | | | | | | | | 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 | numEmbeddedFiles++; #ifdef OF_HAVE_THREADS OFEnsure(OFPlainMutexUnlock(&mutex) == 0); #endif } @implementation OFEmbeddedURIHandler - (OFStream *)openItemAtURI: (OFURI *)URI mode: (OFString *)mode { const char *path; if (![URI.scheme isEqual: @"embedded"] || URI.host.length > 0 || URI.port != nil || URI.user != nil || URI.password != nil || URI.query != nil || URI.fragment != nil) @throw [OFInvalidArgumentException exception]; if (![mode isEqual: @"r"]) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: mode errNo: EROFS]; if ((path = URI.path.UTF8String) == NULL) { @throw [OFInvalidArgumentException exception]; } #ifdef OF_HAVE_THREADS OFEnsure(OFPlainMutexLock(&mutex) == 0); @try { #endif |
︙ | ︙ | |||
106 107 108 109 110 111 112 | } #ifdef OF_HAVE_THREADS } @finally { OFEnsure(OFPlainMutexUnlock(&mutex) == 0); } #endif | | | 106 107 108 109 110 111 112 113 114 115 116 117 | } #ifdef OF_HAVE_THREADS } @finally { OFEnsure(OFPlainMutexUnlock(&mutex) == 0); } #endif @throw [OFOpenItemFailedException exceptionWithURI: URI mode: mode errNo: ENOENT]; } @end |
Modified src/OFEnumerator.h from [514f228b0c] to [bebf66139d].
︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | * doing a fast enumeration. * * @param state Context information for the enumeration * @param objects A pointer to an array where to put the objects * @param count The number of objects that can be stored at objects * @return The number of objects returned in objects or 0 when the enumeration * finished. */ - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id __unsafe_unretained _Nonnull *_Nonnull) objects count: (int)count; @end /** * @class OFEnumerator OFEnumerator.h ObjFW/OFEnumerator.h * * @brief A class which provides methods to enumerate through collections. */ @interface OFEnumerator OF_GENERIC(ObjectType): OFObject <OFFastEnumeration> #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif | > > < < < < > > | 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 | * doing a fast enumeration. * * @param state Context information for the enumeration * @param objects A pointer to an array where to put the objects * @param count The number of objects that can be stored at objects * @return The number of objects returned in objects or 0 when the enumeration * finished. * @throw OFEnumerationMutationException The object was mutated during * enumeration */ - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id __unsafe_unretained _Nonnull *_Nonnull) objects count: (int)count; @end /** * @class OFEnumerator OFEnumerator.h ObjFW/OFEnumerator.h * * @brief A class which provides methods to enumerate through collections. */ @interface OFEnumerator OF_GENERIC(ObjectType): OFObject <OFFastEnumeration> #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif /** * @brief Returns the next object or `nil` if there is none left. * * @return The next object or `nil` if there is none left * @throw OFEnumerationMutationException The object was mutated during * enumeration */ - (nullable ObjectType)nextObject; /** * @brief Returns an array of all remaining objects in the collection. * * @return An array of all remaining objects in the collection. |
︙ | ︙ |
Modified src/OFEpollKernelEventObserver.m from [ddd2075d1e] to [a510ac5746].
︙ | ︙ | |||
27 28 29 30 31 32 33 | #import "OFEpollKernelEventObserver.h" #import "OFArray.h" #import "OFMapTable.h" #import "OFNull.h" #import "OFInitializationFailedException.h" | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #import "OFEpollKernelEventObserver.h" #import "OFArray.h" #import "OFMapTable.h" #import "OFNull.h" #import "OFInitializationFailedException.h" #import "OFObserveKernelEventsFailedException.h" #define eventListSize 64 static const OFMapTableFunctions mapFunctions = { NULL }; @implementation OFEpollKernelEventObserver - (instancetype)init |
︙ | ︙ | |||
100 101 102 103 104 105 106 | memset(&event, 0, sizeof(event)); event.events = (int)events | addEvents; event.data.ptr = object; if (epoll_ctl(_epfd, (events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD), fd, &event) == -1) | > | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | memset(&event, 0, sizeof(event)); event.events = (int)events | addEvents; event.data.ptr = object; if (epoll_ctl(_epfd, (events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD), fd, &event) == -1) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [_FDToEvents setObject: (void *)(events | addEvents) forKey: (void *)((intptr_t)fd + 1)]; } - (void)of_removeObject: (id)object fileDescriptor: (int)fd |
︙ | ︙ | |||
125 126 127 128 129 130 131 | if (epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL) == -1) /* * When an async connect fails, it seems the socket is * automatically removed from epoll, meaning ENOENT is * returned when we try to remove it after it failed. */ if (errno != ENOENT) | | | | 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 | if (epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL) == -1) /* * When an async connect fails, it seems the socket is * automatically removed from epoll, meaning ENOENT is * returned when we try to remove it after it failed. */ if (errno != ENOENT) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [_FDToEvents removeObjectForKey: (void *)((intptr_t)fd + 1)]; } else { struct epoll_event event; memset(&event, 0, sizeof(event)); event.events = (int)events; event.data.ptr = object; if (epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &event) == -1) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [_FDToEvents setObject: (void *)events forKey: (void *)((intptr_t)fd + 1)]; } } |
︙ | ︙ | |||
196 197 198 199 200 201 202 | if ([self of_processReadBuffers]) return; events = epoll_wait(_epfd, eventList, eventListSize, (timeInterval != -1 ? timeInterval * 1000 : -1)); if (events < 0) | > | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | if ([self of_processReadBuffers]) return; events = epoll_wait(_epfd, eventList, eventListSize, (timeInterval != -1 ? timeInterval * 1000 : -1)); if (events < 0) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; for (int i = 0; i < events; i++) { if (eventList[i].events & EPOLLIN) { void *pool = objc_autoreleasePoolPush(); if (eventList[i].data.ptr == nullObject) { char buffer; |
︙ | ︙ |
Modified src/OFFile.h from [70f5f785c7] to [b56cdf66da].
︙ | ︙ | |||
23 24 25 26 27 28 29 | #else typedef struct _OFFileHandle *OFFileHandle; static const OFFileHandle OFInvalidFileHandle = NULL; #endif OF_ASSUME_NONNULL_BEGIN | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #else typedef struct _OFFileHandle *OFFileHandle; static const OFFileHandle OFInvalidFileHandle = NULL; #endif OF_ASSUME_NONNULL_BEGIN @class OFURI; /** * @class OFFile OFFile.h ObjFW/OFFile.h * * @brief A class which provides methods to read and write files. */ OF_SUBCLASSING_RESTRICTED |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | * `w` | Write-only, create or truncate * `wx` | Write-only, create or fail, exclusive * `w+` | Read-write, create or truncate * `w+x` | Read-write, create or fail, exclusive * `a` | Write-only, create or append * `a+` | Read-write, create or append * @return A new autoreleased OFFile */ + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode; /** * @brief Creates a new OFFile with the specified native file handle. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this | > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | * `w` | Write-only, create or truncate * `wx` | Write-only, create or fail, exclusive * `w+` | Read-write, create or truncate * `w+x` | Read-write, create or fail, exclusive * `a` | Write-only, create or append * `a+` | Read-write, create or append * @return A new autoreleased OFFile * @throw OFOpenItemFailedException Opening the file failed */ + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode; /** * @brief Creates a new OFFile with the specified native file handle. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this |
︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 | * `w` | read-write, create, truncate * `wb+` or `w+b` | read-write, create, truncate, binary * `a` | write-only, create, append * `ab` | write-only, create, append, binary * `a+` | read-write, create, append * `ab+` or `a+b` | read-write, create, append, binary * @return An initialized OFFile */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; /** * @brief Initializes an already allocated OFFile. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this | > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | * `w` | read-write, create, truncate * `wb+` or `w+b` | read-write, create, truncate, binary * `a` | write-only, create, append * `ab` | write-only, create, append, binary * `a+` | read-write, create, append * `ab+` or `a+b` | read-write, create, append, binary * @return An initialized OFFile * @throw OFOpenItemFailedException Opening the file failed */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; /** * @brief Initializes an already allocated OFFile. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this |
︙ | ︙ |
Modified src/OFFile.m from [6bda5c55f7] to [57c941bba1].
︙ | ︙ | |||
29 30 31 32 33 34 35 | # include <sys/stat.h> #endif #import "OFFile.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # include <sys/stat.h> #endif #import "OFFile.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFURI.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" |
︙ | ︙ | |||
446 447 448 449 450 451 452 | bytesWritten: 0 errNo: errno]; #endif return (size_t)bytesWritten; } | | > | > > > > > > > > > > > > > > > > > > | | | | | | | 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 | bytesWritten: 0 errNo: errno]; #endif return (size_t)bytesWritten; } - (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset whence: (OFSeekWhence)whence { OFStreamOffset ret; if (_handle == OFInvalidFileHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_AMIGAOS int translatedWhence; switch (whence) { case OFSeekSet: translatedWhence = SEEK_SET; break; case OFSeekCurrent: translatedWhence = SEEK_CUR; break; case OFSeekEnd: translatedWhence = SEEK_END; break; default: @throw [OFSeekFailedException exceptionWithStream: self offset: offset whence: whence errNo: EINVAL]; } # if defined(OF_WINDOWS) ret = _lseeki64(_handle, offset, translatedWhence); # elif defined(HAVE_LSEEK64) ret = lseek64(_handle, offset, translatedWhence); # else ret = lseek(_handle, offset, translatedWhence); # endif if (ret == -1) @throw [OFSeekFailedException exceptionWithStream: self offset: offset whence: whence errNo: errno]; #else LONG translatedWhence; switch (whence) { case OFSeekSet: translatedWhence = OFFSET_BEGINNING; break; case OFSeekCurrent: translatedWhence = OFFSET_CURRENT; break; case OFSeekEnd: translatedWhence = OFFSET_END; break; default: @throw [OFSeekFailedException exceptionWithStream: self offset: offset whence: whence errNo: EINVAL]; |
︙ | ︙ |
Modified src/OFFileManager.h from [e259c02d73] to [1cfc8cfdf6].
︙ | ︙ | |||
35 36 37 38 39 40 41 | # endif #endif @class OFArray OF_GENERIC(ObjectType); @class OFConstantString; @class OFDate; @class OFString; | | | | | | | 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 | # endif #endif @class OFArray OF_GENERIC(ObjectType); @class OFConstantString; @class OFDate; @class OFString; @class OFURI; /** * @brief A key for a file attribute in the file attributes dictionary. * * Possible keys for file URIs are: * * * @ref OFFileSize * * @ref OFFileType * * @ref OFFilePOSIXPermissions * * @ref OFFileOwnerAccountID * * @ref OFFileGroupOwnerAccountID * * @ref OFFileOwnerAccountName * * @ref OFFileGroupOwnerAccountName * * @ref OFFileLastAccessDate * * @ref OFFileModificationDate * * @ref OFFileStatusChangeDate * * @ref OFFileCreationDate * * @ref OFFileSymbolicLinkDestination * * Other URI schemes might not have all keys and might have keys not listed. */ typedef OFConstantString *OFFileAttributeKey; /** * @brief The type of a file. * * Possibles values for file URIs are: * * * @ref OFFileTypeRegular * * @ref OFFileTypeDirectory * * @ref OFFileTypeSymbolicLink * * @ref OFFileTypeFIFO * * @ref OFFileTypeCharacterSpecial * * @ref OFFileTypeBlockSpecial * * @ref OFFileTypeSocket * * @ref OFFileTypeUnknown * * Other URI schemes might not have all types and might have types not listed. */ typedef OFConstantString *OFFileAttributeType; /** * @brief A dictionary mapping keys of type @ref OFFileAttributeKey to their * attribute values. */ |
︙ | ︙ | |||
255 256 257 258 259 260 261 262 263 264 265 | #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFFileManager *defaultManager; #endif #ifdef OF_HAVE_FILES /** * @brief The path of the current working directory. */ @property (readonly, nonatomic) OFString *currentDirectoryPath; /** | > > | > > | > > | | | > > > > | > > > > > | | | > > > > > > > | | | | > > | | | | > > | > > > | | > > > | | | > > > > | > > | | | > > > > | > > | > > | > > > | | > > > > > | > > > > > > > > | | > > > > > > > > > > | > | | | > > > | > > > | | | | > > > > > | > > > | | | > > | | | | | | | | | | | | | | 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 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 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 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFFileManager *defaultManager; #endif #ifdef OF_HAVE_FILES /** * @brief The path of the current working directory. * * @throw OFGetCurrentDirectoryFailedException Couldn't get current directory */ @property (readonly, nonatomic) OFString *currentDirectoryPath; /** * @brief The URI of the current working directory. * * @throw OFGetCurrentDirectoryFailedException Couldn't get current directory */ @property (readonly, nonatomic) OFURI *currentDirectoryURI; #endif /** * @brief Returns the default file manager. */ + (OFFileManager *)defaultManager; #ifdef OF_HAVE_FILES /** * @brief Returns the attributes for the item at the specified path. * * @param path The path to return the attributes for * @return A dictionary of attributes for the specified path, with the keys of * type @ref OFFileAttributeKey * @throw OFGetItemAttributesFailedException Failed to get the attributes of * the item */ - (OFFileAttributes)attributesOfItemAtPath: (OFString *)path; #endif /** * @brief Returns the attributes for the item at the specified URI. * * @param URI The URI to return the attributes for * @return A dictionary of attributes for the specified URI, with the keys of * type @ref OFFileAttributeKey * @throw OFGetItemAttributesFailedException Failed to get the attributes of * the item * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (OFFileAttributes)attributesOfItemAtURI: (OFURI *)URI; #ifdef OF_HAVE_FILES /** * @brief Sets the attributes for the item at the specified path. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified path * @param path The path of the item to set the attributes for * @throw OFSetItemAttributesFailedException Failed to set the attributes of * the item * @throw OFNotImplementedException Setting one or more of the specified * attributes is not implemented for the * specified item */ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtPath: (OFString *)path; #endif /** * @brief Sets the attributes for the item at the specified URI. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified URI * @param URI The URI of the item to set the attributes for * @throw OFSetItemAttributesFailedException Failed to set the attributes of * the item * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme * @throw OFNotImplementedException Setting one or more of the specified * attributes is not implemented for the * specified item */ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURI: (OFURI *)URI; #ifdef OF_HAVE_FILES /** * @brief Checks whether a file exists at the specified path. * * @param path The path to check * @return A boolean whether there is a file at the specified path */ - (bool)fileExistsAtPath: (OFString *)path; #endif /** * @brief Checks whether a file exists at the specified URI. * * @param URI The URI to check * @return A boolean whether there is a file at the specified URI * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (bool)fileExistsAtURI: (OFURI *)URI; #ifdef OF_HAVE_FILES /** * @brief Checks whether a directory exists at the specified path. * * @param path The path to check * @return A boolean whether there is a directory at the specified path */ - (bool)directoryExistsAtPath: (OFString *)path; #endif /** * @brief Checks whether a directory exists at the specified URI. * * @param URI The URI to check * @return A boolean whether there is a directory at the specified URI * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (bool)directoryExistsAtURI: (OFURI *)URI; #ifdef OF_HAVE_FILES /** * @brief Creates a directory at the specified path. * * @param path The path of the directory to create * @throw OFCreateDirectoryFailedException Creating the directory failed */ - (void)createDirectoryAtPath: (OFString *)path; /** * @brief Creates a directory at the specified path. * * @param path The path of the directory to create * @param createParents Whether to create the parents of the directory * @throw OFCreateDirectoryFailedException Creating the directory or one of its * parents failed */ - (void)createDirectoryAtPath: (OFString *)path createParents: (bool)createParents; #endif /** * @brief Creates a directory at the specified URI. * * @param URI The URI of the directory to create * @throw OFCreateDirectoryFailedException Creating the directory failed * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (void)createDirectoryAtURI: (OFURI *)URI; /** * @brief Creates a directory at the specified URI. * * @param URI The URI of the directory to create * @param createParents Whether to create the parents of the directory * @throw OFCreateDirectoryFailedException Creating the directory or one of its * parents failed * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (void)createDirectoryAtURI: (OFURI *)URI createParents: (bool)createParents; #ifdef OF_HAVE_FILES /** * @brief Returns an array with the items in the specified directory. * * @note `.` and `..` are not part of the returned array. * * @param path The path to the directory whose items should be returned * @return An array of OFString with the items in the specified directory * @throw OFOpenItemFailedException Opening the directory failed * @throw OFReadFailedException Reading from the directory failed */ - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path; #endif /** * @brief Returns an array with the URIs of the items in the specified * directory. * * @note `.` and `..` are not part of the returned array. * * @param URI The URI to the directory whose items should be returned * @return An array with the URIs of the items in the specified directory * @throw OFOpenItemFailedException Opening the directory failed * @throw OFReadFailedException Reading from the directory failed * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (OFArray OF_GENERIC(OFURI *) *)contentsOfDirectoryAtURI: (OFURI *)URI; #ifdef OF_HAVE_FILES /** * @brief Returns an array with all subpaths of the specified directory. * * @note `.` and `..` (of the directory itself or any subdirectory) are not * part of the returned array. * * @param path The path to the directory whose subpaths should be returned * @return An array of OFString with the subpaths of the specified directory */ - (OFArray OF_GENERIC(OFString *) *)subpathsOfDirectoryAtPath: (OFString *)path; /** * @brief Changes the current working directory. * * @param path The new directory to change to * @throw OFChangeCurrentDirectoryFailedException Changing the current working * directory failed */ - (void)changeCurrentDirectoryPath: (OFString *)path; /** * @brief Changes the current working directory. * * @param URI The new directory to change to * @throw OFChangeCurrentDirectoryFailedException Changing the current working * directory failed */ - (void)changeCurrentDirectoryURI: (OFURI *)URI; /** * @brief Copies a file, directory or symbolic link (if supported by the OS). * * The destination path must be a full path, which means it must include the * name of the item. * * If an item already exists, the copy operation fails. This is also the case * if a directory is copied and an item already exists in the destination * directory. * * @param source The file, directory or symbolic link to copy * @param destination The destination path * @throw OFCopyItemFailedException Copying failed * @throw OFCreateDirectoryFailedException Creating a destination directory * failed */ - (void)copyItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Copies a file, directory or symbolic link (if supported by the OS). * * The destination URI must have a full path, which means it must include the * name of the item. * * If an item already exists, the copy operation fails. This is also the case * if a directory is copied and an item already exists in the destination * directory. * * @param source The file, directory or symbolic link to copy * @param destination The destination URI * @throw OFCopyItemFailedException Copying failed * @throw OFCreateDirectoryFailedException Creating a destination directory * failed * @throw OFUnsupportedProtocolException No handler is registered for either of * the URI's scheme */ - (void)copyItemAtURI: (OFURI *)source toURI: (OFURI *)destination; #ifdef OF_HAVE_FILES /** * @brief Moves an item. * * The destination path must be a full path, which means it must include the * name of the item. * * If the destination is on a different logical device, the source will be * copied to the destination using @ref copyItemAtPath:toPath: and the source * removed using @ref removeItemAtPath:. * * @param source The item to rename * @param destination The new name for the item * @throw OFMoveItemFailedException Moving failed * @throw OFCopyItemFailedException Copying (to move between different devices) * failed * @throw OFRemoveItemFailedException Removing the source after copying to the * destination (to move between different * devices) failed * @throw OFCreateDirectoryFailedException Creating a destination directory * failed */ - (void)moveItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Moves an item. * * The destination URI must have a full path, which means it must include the * name of the item. * * If the destination is on a different logical device or uses a different * scheme, the source will be copied to the destination using * @ref copyItemAtURI:toURI: and the source removed using @ref removeItemAtURI:. * * @param source The item to rename * @param destination The new name for the item * @throw OFMoveItemFailedException Moving failed * @throw OFCopyItemFailedException Copying (to move between different devices) * failed * @throw OFRemoveItemFailedException Removing the source after copying to the * destination (to move between different * devices) failed * @throw OFCreateDirectoryFailedException Creating a destination directory * failed * @throw OFUnsupportedProtocolException No handler is registered for either of * the URI's scheme */ - (void)moveItemAtURI: (OFURI *)source toURI: (OFURI *)destination; #ifdef OF_HAVE_FILES /** * @brief Removes the item at the specified path. * * If the item at the specified path is a directory, it is removed recursively. * * @param path The path to the item which should be removed * @throw OFRemoveItemFailedException Removing the item failed */ - (void)removeItemAtPath: (OFString *)path; #endif /** * @brief Removes the item at the specified URI. * * If the item at the specified URI is a directory, it is removed recursively. * * @param URI The URI to the item which should be removed * @throw OFRemoveItemFailedException Removing the item failed * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (void)removeItemAtURI: (OFURI *)URI; #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS /** * @brief Creates a hard link for the specified item. * * The destination path must be a full path, which means it must include the * name of the item. * * This method is not available on some systems. * * @param source The path to the item for which a link should be created * @param destination The path to the item which should link to the source * @throw OFLinkItemFailedException Linking the item failed * @throw OFNotImplementedException Hardlinks are not implemented for the * specified URI */ - (void)linkItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Creates a hard link for the specified item. * * The destination URI must have a full path, which means it must include the * name of the item. * * This method is not available for all URIs. * * @param source The URI to the item for which a link should be created * @param destination The URI to the item which should link to the source * @throw OFLinkItemFailedException Linking the item failed * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme * @throw OFNotImplementedException Hardlinks are not implemented for the * specified URI */ - (void)linkItemAtURI: (OFURI *)source toURI: (OFURI *)destination; #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS /** * @brief Creates a symbolic link for an item. * * The destination path must be a full path, which means it must include the * name of the item. * * This method is not available on some systems. * * @note On Windows, this requires at least Windows Vista and administrator * privileges! * * @param path The path to the item which should symbolically link to the target * @param target The target of the symbolic link * @throw OFCreateSymbolicLinkFailedException Creating the symbolic link failed * @throw OFNotImplementedException Symbolic links are not implemented for the * specified URI */ - (void)createSymbolicLinkAtPath: (OFString *)path withDestinationPath: (OFString *)target; #endif /** * @brief Creates a symbolic link for an item. * * The destination URI must have a full path, which means it must include the * name of the item. * * This method is not available for all URIs. * * @note On Windows, this requires at least Windows Vista and administrator * privileges! * * @param URI The URI to the item which should symbolically link to the target * @param target The target of the symbolic link * @throw OFUnsupportedProtocolException No handler is registered for the URI's * scheme */ - (void)createSymbolicLinkAtURI: (OFURI *)URI withDestinationPath: (OFString *)target; @end @interface OFDictionary (FileAttributes) /** * @brief The @ref OFFileSize key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) unsigned long long fileSize; /** * @brief The @ref OFFileType key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFFileAttributeType fileType; /** * @brief The @ref OFFilePOSIXPermissions key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) unsigned long filePOSIXPermissions; /** * @brief The @ref OFFileOwnerAccountID key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) unsigned long fileOwnerAccountID; /** * @brief The @ref OFFileGroupOwnerAccountID key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) unsigned long fileGroupOwnerAccountID; /** * @brief The @ref OFFileOwnerAccountName key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFString *fileOwnerAccountName; /** * @brief The @ref OFFileGroupOwnerAccountName key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFString *fileGroupOwnerAccountName; /** * @brief The @ref OFFileLastAccessDate key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFDate *fileLastAccessDate; /** * @brief The @ref OFFileModificationDate key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFDate *fileModificationDate; /** * @brief The @ref OFFileStatusChangeDate key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFDate *fileStatusChangeDate; /** * @brief The @ref OFFileCreationDate key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFDate *fileCreationDate; /** * @brief The @ref OFFileSymbolicLinkDestination key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFString *fileSymbolicLinkDestination; @end OF_ASSUME_NONNULL_END |
Modified src/OFFileManager.m from [8b48822fc3] to [5dfeac045a].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #define OF_FILE_MANAGER_M #include <errno.h> #include <limits.h> #include "unistd_wrapper.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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #define OF_FILE_MANAGER_M #include <errno.h> #include <limits.h> #include "unistd_wrapper.h" #include "platform.h" #ifdef OF_PSP # include <sys/syslimits.h> #endif #import "OFArray.h" #import "OFDate.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFStream.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFURI.h" #import "OFURIHandler.h" #import "OFChangeCurrentDirectoryFailedException.h" #import "OFCopyItemFailedException.h" #import "OFCreateDirectoryFailedException.h" #import "OFGetCurrentDirectoryFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFMoveItemFailedException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFRemoveItemFailedException.h" #import "OFGetItemAttributesFailedException.h" #import "OFUndefinedKeyException.h" #import "OFUnsupportedProtocolException.h" #ifdef OF_WINDOWS # include <windows.h> # include <direct.h> # include <ntdef.h> |
︙ | ︙ | |||
167 168 169 170 171 172 173 | return [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; # else char buffer[PATH_MAX]; if ((getcwd(buffer, PATH_MAX)) == NULL) | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | return [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; # else char buffer[PATH_MAX]; if ((getcwd(buffer, PATH_MAX)) == NULL) @throw [OFGetCurrentDirectoryFailedException exceptionWithErrNo: errno]; # ifdef OF_DJGPP /* * For some reason, getcwd() returns forward slashes on DJGPP, even * though the native format is to use backwards slashes. */ for (char *tmp = buffer; *tmp != '\0'; tmp++) if (*tmp == '/') *tmp = '\\'; # endif return [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; # endif } - (OFURI *)currentDirectoryURI { void *pool = objc_autoreleasePoolPush(); OFURI *ret; ret = [OFURI fileURIWithPath: self.currentDirectoryPath]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif - (OFFileAttributes)attributesOfItemAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; return [URIHandler attributesOfItemAtURI: URI]; } #ifdef OF_HAVE_FILES - (OFFileAttributes)attributesOfItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFFileAttributes ret; ret = [self attributesOfItemAtURI: [OFURI fileURIWithPath: path]]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; [URIHandler setAttributes: attributes ofItemAtURI: URI]; } #ifdef OF_HAVE_FILES - (void)setAttributes: (OFFileAttributes)attributes ofItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self setAttributes: attributes ofItemAtURI: [OFURI fileURIWithPath: path]]; objc_autoreleasePoolPop(pool); } #endif - (bool)fileExistsAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; return [URIHandler fileExistsAtURI: URI]; } #ifdef OF_HAVE_FILES - (bool)fileExistsAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); bool ret; ret = [self fileExistsAtURI: [OFURI fileURIWithPath: path]]; objc_autoreleasePoolPop(pool); return ret; } #endif - (bool)directoryExistsAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; return [URIHandler directoryExistsAtURI: URI]; } #ifdef OF_HAVE_FILES - (bool)directoryExistsAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); bool ret; ret = [self directoryExistsAtURI: [OFURI fileURIWithPath: path]]; objc_autoreleasePoolPop(pool); return ret; } #endif - (void)createDirectoryAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; [URIHandler createDirectoryAtURI: URI]; } - (void)createDirectoryAtURI: (OFURI *)URI createParents: (bool)createParents { void *pool = objc_autoreleasePoolPush(); OFMutableURI *mutableURI; OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFURI *) *componentURIs; size_t componentURIsCount; ssize_t i; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (!createParents) { [self createDirectoryAtURI: URI]; return; } /* * Try blindly creating the directory first. * * The reason for this is that we might be sandboxed, so attempting to * create any of the parent directories will fail, while creating the * directory itself will work. */ if ([self directoryExistsAtURI: URI]) return; @try { [self createDirectoryAtURI: URI]; return; } @catch (OFCreateDirectoryFailedException *e) { /* * If we didn't fail because any of the parents is missing, * there is no point in trying to create the parents. */ if (e.errNo != ENOENT) @throw e; } /* * Because we might be sandboxed (and for remote URIs don't even know * anything at all), we generate the URI for every component. We then * iterate them in reverse order until we find the first existing * directory, and then create subdirectories from there. */ mutableURI = [[URI mutableCopy] autorelease]; mutableURI.percentEncodedPath = @"/"; components = URI.pathComponents; componentURIs = [OFMutableArray arrayWithCapacity: components.count]; for (OFString *component in components) { [mutableURI appendPathComponent: component]; if (![mutableURI.percentEncodedPath isEqual: @"/"]) [componentURIs addObject: [[mutableURI copy] autorelease]]; } componentURIsCount = componentURIs.count; for (i = componentURIsCount - 1; i > 0; i--) { if ([self directoryExistsAtURI: [componentURIs objectAtIndex: i]]) break; } if (++i == (ssize_t)componentURIsCount) { /* * The URI exists, even though before we made sure it did not. * That means it was created in the meantime by something else, * so we're done here. */ objc_autoreleasePoolPop(pool); return; } for (; i < (ssize_t)componentURIsCount; i++) [self createDirectoryAtURI: [componentURIs objectAtIndex: i]]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_FILES - (void)createDirectoryAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self createDirectoryAtURI: [OFURI fileURIWithPath: path]]; objc_autoreleasePoolPop(pool); } - (void)createDirectoryAtPath: (OFString *)path createParents: (bool)createParents { void *pool = objc_autoreleasePoolPush(); [self createDirectoryAtURI: [OFURI fileURIWithPath: path] createParents: createParents]; objc_autoreleasePoolPop(pool); } #endif - (OFArray OF_GENERIC(OFURI *) *)contentsOfDirectoryAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; return [URIHandler contentsOfDirectoryAtURI: URI]; } #ifdef OF_HAVE_FILES - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFURI *) *URIs; OFMutableArray OF_GENERIC(OFString *) *ret; URIs = [self contentsOfDirectoryAtURI: [OFURI fileURIWithPath: path]]; ret = [OFMutableArray arrayWithCapacity: URIs.count]; for (OFURI *URI in URIs) [ret addObject: URI.lastPathComponent]; [ret makeImmutable]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; |
︙ | ︙ | |||
511 512 513 514 515 516 517 | errNo = ENOENT; break; default: errNo = 0; break; } | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | errNo = ENOENT; break; default: errNo = 0; break; } @throw [OFChangeCurrentDirectoryFailedException exceptionWithPath: path errNo: errNo]; } oldLock = CurrentDir(lock); if (!dirChanged) |
︙ | ︙ | |||
536 537 538 539 540 541 542 | status = _wchdir(path.UTF16String); else # endif status = chdir( [path cStringWithEncoding: [OFLocale encoding]]); if (status != 0) | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | 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 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 | status = _wchdir(path.UTF16String); else # endif status = chdir( [path cStringWithEncoding: [OFLocale encoding]]); if (status != 0) @throw [OFChangeCurrentDirectoryFailedException exceptionWithPath: path errNo: errno]; # endif } - (void)changeCurrentDirectoryURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); [self changeCurrentDirectoryPath: URI.fileSystemRepresentation]; objc_autoreleasePoolPop(pool); } - (void)copyItemAtPath: (OFString *)source toPath: (OFString *)destination { void *pool = objc_autoreleasePoolPush(); [self copyItemAtURI: [OFURI fileURIWithPath: source] toURI: [OFURI fileURIWithPath: destination]]; objc_autoreleasePoolPop(pool); } #endif - (void)copyItemAtURI: (OFURI *)source toURI: (OFURI *)destination { void *pool; OFURIHandler *URIHandler; OFFileAttributes attributes; OFFileAttributeType type; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); if ((URIHandler = [OFURIHandler handlerForURI: source]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: source]; if ([URIHandler copyItemAtURI: source toURI: destination]) return; if ([self fileExistsAtURI: destination]) @throw [OFCopyItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: EEXIST]; @try { attributes = [self attributesOfItemAtURI: source]; } @catch (OFGetItemAttributesFailedException *e) { @throw [OFCopyItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: e.errNo]; } type = attributes.fileType; if ([type isEqual: OFFileTypeDirectory]) { OFArray OF_GENERIC(OFURI *) *contents; @try { [self createDirectoryAtURI: destination]; @try { OFFileAttributeKey key = OFFilePOSIXPermissions; OFNumber *permissions = [attributes objectForKey: key]; OFFileAttributes destinationAttributes; if (permissions != nil) { destinationAttributes = [OFDictionary dictionaryWithObject: permissions forKey: key]; [self setAttributes: destinationAttributes ofItemAtURI: destination]; } } @catch (OFNotImplementedException *e) { } contents = [self contentsOfDirectoryAtURI: source]; } @catch (id e) { /* * Only convert exceptions to OFCopyItemFailedException * that have an errNo property. This covers all I/O * related exceptions from the operations used to copy * an item, all others should be left as is. */ if ([e respondsToSelector: @selector(errNo)]) @throw [OFCopyItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: [e errNo]]; @throw e; } for (OFURI *item in contents) { void *pool2 = objc_autoreleasePoolPush(); OFURI *destinationURI = [destination URIByAppendingPathComponent: item.lastPathComponent]; [self copyItemAtURI: item toURI: destinationURI]; objc_autoreleasePoolPop(pool2); } } else if ([type isEqual: OFFileTypeRegular]) { size_t pageSize = [OFSystemInfo pageSize]; OFStream *sourceStream = nil; OFStream *destinationStream = nil; char *buffer; buffer = OFAllocMemory(1, pageSize); @try { sourceStream = [OFURIHandler openItemAtURI: source mode: @"r"]; destinationStream = [OFURIHandler openItemAtURI: destination mode: @"w"]; while (!sourceStream.atEndOfStream) { size_t length; length = [sourceStream readIntoBuffer: buffer length: pageSize]; |
︙ | ︙ | |||
685 686 687 688 689 690 691 | if (permissions != nil) { destinationAttributes = [OFDictionary dictionaryWithObject: permissions forKey: key]; [self setAttributes: destinationAttributes | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 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 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 | if (permissions != nil) { destinationAttributes = [OFDictionary dictionaryWithObject: permissions forKey: key]; [self setAttributes: destinationAttributes ofItemAtURI: destination]; } } @catch (OFNotImplementedException *e) { } } @catch (id e) { /* * Only convert exceptions to OFCopyItemFailedException * that have an errNo property. This covers all I/O * related exceptions from the operations used to copy * an item, all others should be left as is. */ if ([e respondsToSelector: @selector(errNo)]) @throw [OFCopyItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: [e errNo]]; @throw e; } @finally { [sourceStream close]; [destinationStream close]; OFFreeMemory(buffer); } } else if ([type isEqual: OFFileTypeSymbolicLink]) { @try { OFString *linkDestination = attributes.fileSymbolicLinkDestination; [self createSymbolicLinkAtURI: destination withDestinationPath: linkDestination]; } @catch (id e) { /* * Only convert exceptions to OFCopyItemFailedException * that have an errNo property. This covers all I/O * related exceptions from the operations used to copy * an item, all others should be left as is. */ if ([e respondsToSelector: @selector(errNo)]) @throw [OFCopyItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: [e errNo]]; @throw e; } } else @throw [OFCopyItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: EINVAL]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_FILES - (void)moveItemAtPath: (OFString *)source toPath: (OFString *)destination { void *pool = objc_autoreleasePoolPush(); [self moveItemAtURI: [OFURI fileURIWithPath: source] toURI: [OFURI fileURIWithPath: destination]]; objc_autoreleasePoolPop(pool); } #endif - (void)moveItemAtURI: (OFURI *)source toURI: (OFURI *)destination { void *pool; OFURIHandler *URIHandler; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); if ((URIHandler = [OFURIHandler handlerForURI: source]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: source]; @try { if ([URIHandler moveItemAtURI: source toURI: destination]) return; } @catch (OFMoveItemFailedException *e) { if (e.errNo != EXDEV) @throw e; } if ([self fileExistsAtURI: destination]) @throw [OFMoveItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: EEXIST]; @try { [self copyItemAtURI: source toURI: destination]; } @catch (OFCopyItemFailedException *e) { [self removeItemAtURI: destination]; @throw [OFMoveItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: e.errNo]; } @try { [self removeItemAtURI: source]; } @catch (OFRemoveItemFailedException *e) { @throw [OFMoveItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: e.errNo]; } objc_autoreleasePoolPop(pool); } - (void)removeItemAtURI: (OFURI *)URI { OFURIHandler *URIHandler; if (URI == nil) @throw [OFInvalidArgumentException exception]; if ((URIHandler = [OFURIHandler handlerForURI: URI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; [URIHandler removeItemAtURI: URI]; } #ifdef OF_HAVE_FILES - (void)removeItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self removeItemAtURI: [OFURI fileURIWithPath: path]]; objc_autoreleasePoolPop(pool); } #endif - (void)linkItemAtURI: (OFURI *)source toURI: (OFURI *)destination { void *pool = objc_autoreleasePoolPush(); OFURIHandler *URIHandler; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; if (![destination.scheme isEqual: source.scheme]) @throw [OFInvalidArgumentException exception]; URIHandler = [OFURIHandler handlerForURI: source]; if (URIHandler == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: source]; [URIHandler linkItemAtURI: source toURI: destination]; objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS - (void)linkItemAtPath: (OFString *)source toPath: (OFString *)destination { void *pool = objc_autoreleasePoolPush(); [self linkItemAtURI: [OFURI fileURIWithPath: source] toURI: [OFURI fileURIWithPath: destination]]; objc_autoreleasePoolPop(pool); } #endif - (void)createSymbolicLinkAtURI: (OFURI *)URI withDestinationPath: (OFString *)target { void *pool = objc_autoreleasePoolPush(); OFURIHandler *URIHandler; if (URI == nil || target == nil) @throw [OFInvalidArgumentException exception]; URIHandler = [OFURIHandler handlerForURI: URI]; if (URIHandler == nil) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; [URIHandler createSymbolicLinkAtURI: URI withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS - (void)createSymbolicLinkAtPath: (OFString *)path withDestinationPath: (OFString *)target { void *pool = objc_autoreleasePoolPush(); [self createSymbolicLinkAtURI: [OFURI fileURIWithPath: path] withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #endif @end @implementation OFDefaultFileManager |
︙ | ︙ |
Renamed and modified src/OFFileURLHandler.h [bc6fd1985b] to src/OFFileURIHandler.h [24ec18a27d].
︙ | ︙ | |||
9 10 11 12 13 14 15 | * * 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. */ | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * * 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 "OFURIHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFFileURIHandler: OFURIHandler + (bool)of_directoryExistsAtPath: (OFString *)path OF_DIRECT; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFFileURLHandler.m [50a5ea9a56] to src/OFFileURIHandler.m [d74cbf6f89].
︙ | ︙ | |||
21 22 23 24 25 26 27 | #include <math.h> #ifdef HAVE_DIRENT_H # include <dirent.h> #endif #include "unistd_wrapper.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 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 | #include <math.h> #ifdef HAVE_DIRENT_H # include <dirent.h> #endif #include "unistd_wrapper.h" #include "platform.h" #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #include <sys/time.h> #ifdef OF_WINDOWS # include <utime.h> #endif #ifdef HAVE_PWD_H # include <pwd.h> #endif #ifdef HAVE_GRP_H # include <grp.h> #endif #import "OFFileURIHandler.h" #import "OFArray.h" #import "OFDate.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFSystemInfo.h" #import "OFURI.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFCreateDirectoryFailedException.h" #import "OFCreateSymbolicLinkFailedException.h" #import "OFGetItemAttributesFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFLinkItemFailedException.h" #import "OFMoveItemFailedException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFRemoveItemFailedException.h" #import "OFSetItemAttributesFailedException.h" #ifdef OF_WINDOWS # include <windows.h> # include <direct.h> # include <ntdef.h> # include <wchar.h> #endif #ifdef OF_AMIGAOS # include <proto/exec.h> # include <proto/dos.h> # include <proto/locale.h> # ifdef OF_AMIGAOS4 # define DeleteFile(path) Delete(path) # endif #endif #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) typedef struct { OFStreamOffset st_size; unsigned int st_mode; OFTimeInterval st_atime, st_mtime, st_ctime; # ifdef OF_WINDOWS # define HAVE_STRUCT_STAT_ST_BIRTHTIME OFTimeInterval st_birthtime; DWORD fileAttributes; # endif |
︙ | ︙ | |||
138 139 140 141 142 143 144 | filetimeToTimeInterval(const FILETIME *filetime) { return (double)((int64_t)filetime->dwHighDateTime << 32 | filetime->dwLowDateTime) / 10000000.0 - 11644473600.0; } static int | | | | 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 | filetimeToTimeInterval(const FILETIME *filetime) { return (double)((int64_t)filetime->dwHighDateTime << 32 | filetime->dwLowDateTime) / 10000000.0 - 11644473600.0; } static int lastError(void) { switch (GetLastError()) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_NO_MORE_FILES: return ENOENT; case ERROR_ACCESS_DENIED: return EACCES; case ERROR_DIRECTORY: return ENOTDIR; case ERROR_NOT_READY: return EBUSY; default: return EIO; } } #endif #ifdef OF_AMIGAOS static int lastError(void) { switch (IoErr()) { case ERROR_DELETE_PROTECTED: case ERROR_READ_PROTECTED: case ERROR_WRITE_PROTECTED: return EACCES; case ERROR_DISK_NOT_VALIDATED: |
︙ | ︙ | |||
207 208 209 210 211 212 213 | GetFileExInfoStandard, &data); else success = GetFileAttributesExA( [path cStringWithEncoding: [OFLocale encoding]], GetFileExInfoStandard, &data); if (!success) | | | | 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 | GetFileExInfoStandard, &data); else success = GetFileAttributesExA( [path cStringWithEncoding: [OFLocale encoding]], GetFileExInfoStandard, &data); if (!success) return lastError(); 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) return lastError(); @try { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) /* Race? Indicate to try again. */ return EAGAIN; |
︙ | ︙ | |||
264 265 266 267 268 269 270 | # endif OFTimeInterval timeInterval; struct Locale *locale; struct DateStamp *date; if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]], SHARED_LOCK)) == 0) | | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | # endif OFTimeInterval timeInterval; struct Locale *locale; struct DateStamp *date; if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]], SHARED_LOCK)) == 0) return lastError(); # if defined(OF_MORPHOS) if (!Examine64(lock, &fib, TAG_DONE)) { # elif defined(OF_AMIGAOS4) if ((ed = ExamineObjectTags(EX_FileLockInput, lock, TAG_END)) == NULL) { # else if (!Examine(lock, &fib)) { # endif int error = lastError(); UnLock(lock); return error; } UnLock(lock); # if defined(OF_MORPHOS) |
︙ | ︙ | |||
453 454 455 456 457 458 459 | # endif #endif } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS static void setSymbolicLinkDestinationAttribute(OFMutableFileAttributes attributes, | | | | | | | | | | | | | | | 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 | # endif #endif } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS static void setSymbolicLinkDestinationAttribute(OFMutableFileAttributes attributes, OFURI *URI) { OFString *path = URI.fileSystemRepresentation; # ifndef OF_WINDOWS OFStringEncoding encoding = [OFLocale encoding]; char destinationC[PATH_MAX]; ssize_t length; OFString *destination; length = readlink([path cStringWithEncoding: encoding], destinationC, PATH_MAX); if (length < 0) @throw [OFGetItemAttributesFailedException exceptionWithURI: URI errNo: errno]; destination = [OFString stringWithCString: destinationC encoding: encoding length: length]; [attributes setObject: destination forKey: OFFileSymbolicLinkDestination]; # else HANDLE handle; OFString *destination; if (createSymbolicLinkWFuncPtr == NULL) return; if ((handle = CreateFileW(path.UTF16String, 0, (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL)) == INVALID_HANDLE_VALUE) @throw [OFGetItemAttributesFailedException exceptionWithURI: URI errNo: lastError()]; @try { union { char bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER data; } buffer; DWORD size; wchar_t *tmp; if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer.bytes, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &size, NULL)) @throw [OFGetItemAttributesFailedException exceptionWithURI: URI errNo: lastError()]; if (buffer.data.ReparseTag != IO_REPARSE_TAG_SYMLINK) @throw [OFGetItemAttributesFailedException exceptionWithURI: URI errNo: lastError()]; # define slrb buffer.data.SymbolicLinkReparseBuffer tmp = slrb.PathBuffer + (slrb.SubstituteNameOffset / sizeof(wchar_t)); destination = [OFString stringWithUTF16String: tmp |
︙ | ︙ | |||
531 532 533 534 535 536 537 | } @finally { CloseHandle(handle); } # endif } #endif | | | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | } @finally { CloseHandle(handle); } # endif } #endif @implementation OFFileURIHandler + (void)initialize { #ifdef OF_WINDOWS HMODULE module; #endif if (self != [OFFileURIHandler class]) return; #if defined(OF_FILE_MANAGER_SUPPORTS_OWNER) && defined(OF_HAVE_THREADS) passwdMutex = [[OFMutex alloc] init]; atexit(releasePasswdMutex); #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) |
︙ | ︙ | |||
583 584 585 586 587 588 589 | if (statWrapper(path, &s) != 0) return false; return S_ISDIR(s.st_mode); } | | | | | | | | | | | | | | | 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 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 | if (statWrapper(path, &s) != 0) return false; return S_ISDIR(s.st_mode); } - (OFStream *)openItemAtURI: (OFURI *)URI mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFFile *file = [[OFFile alloc] initWithPath: URI.fileSystemRepresentation mode: mode]; objc_autoreleasePoolPop(pool); return [file autorelease]; } - (OFFileAttributes)attributesOfItemAtURI: (OFURI *)URI { OFMutableFileAttributes ret = [OFMutableDictionary dictionary]; void *pool = objc_autoreleasePoolPush(); OFString *path; int error; Stat s; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![[URI scheme] isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URI.fileSystemRepresentation; if ((error = lstatWrapper(path, &s)) != 0) @throw [OFGetItemAttributesFailedException exceptionWithURI: URI errNo: error]; if (s.st_size < 0) @throw [OFOutOfRangeException exception]; [ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size] forKey: OFFileSize]; setTypeAttribute(ret, &s); [ret setObject: [NSNumber numberWithUnsignedLong: s.st_mode] forKey: OFFilePOSIXPermissions]; setOwnerAndGroupAttributes(ret, &s); setDateAttributes(ret, &s); #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS if (S_ISLNK(s.st_mode)) setSymbolicLinkDestinationAttribute(ret, URI); #endif objc_autoreleasePoolPop(pool); return ret; } - (void)of_setLastAccessDate: (OFDate *)lastAccessDate andModificationDate: (OFDate *)modificationDate ofItemAtURI: (OFURI *)URI attributes: (OFFileAttributes)attributes OF_DIRECT { OFString *path = URI.fileSystemRepresentation; OFFileAttributeKey attributeKey = (modificationDate != nil ? OFFileModificationDate : OFFileLastAccessDate); if (lastAccessDate == nil) lastAccessDate = modificationDate; if (modificationDate == nil) modificationDate = lastAccessDate; #if defined(OF_WINDOWS) if (_wutime64FuncPtr != NULL) { struct __utimbuf64 times = { .actime = (__time64_t)lastAccessDate.timeIntervalSince1970, .modtime = (__time64_t)modificationDate.timeIntervalSince1970 }; if (_wutime64FuncPtr([path UTF16String], ×) != 0) @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: errno]; } else { struct _utimbuf times = { .actime = (time_t)lastAccessDate.timeIntervalSince1970, .modtime = (time_t)modificationDate.timeIntervalSince1970 }; int status; if ([OFSystemInfo isWindowsNT]) status = _wutime([path UTF16String], ×); else status = _utime( [path cStringWithEncoding: [OFLocale encoding]], ×); if (status != 0) @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: errno]; } #elif defined(OF_AMIGAOS) /* AmigaOS does not support access time. */ OFTimeInterval modificationTime = |
︙ | ︙ | |||
724 725 726 727 728 729 730 | if (!SetDate([path cStringWithEncoding: [OFLocale encoding]], &date) != 0) # else if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]], &date) != 0) # endif @throw [OFSetItemAttributesFailedException | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 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 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 1041 1042 1043 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 | if (!SetDate([path cStringWithEncoding: [OFLocale encoding]], &date) != 0) # else if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]], &date) != 0) # endif @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: lastError()]; #else OFTimeInterval lastAccessTime = lastAccessDate.timeIntervalSince1970; OFTimeInterval modificationTime = modificationDate.timeIntervalSince1970; struct timeval times[2] = { { .tv_sec = (time_t)lastAccessTime, .tv_usec = (int)((lastAccessTime - times[0].tv_sec) * 1000000) }, { .tv_sec = (time_t)modificationTime, .tv_usec = (int)((modificationTime - times[1].tv_sec) * 1000000) }, }; if (utimes([path cStringWithEncoding: [OFLocale encoding]], times) != 0) @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: errno]; #endif } - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURI: (OFURI *)URI attributes: (OFFileAttributes)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS mode_t mode = (mode_t)permissions.unsignedLongValue; OFString *path = URI.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 exceptionWithURI: URI attributes: attributes failedAttribute: OFFilePOSIXPermissions errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)of_setOwnerAccountName: (OFString *)owner andGroupOwnerAccountName: (OFString *)group ofItemAtURI: (OFURI *)URI attributeKey: (OFFileAttributeKey)attributeKey attributes: (OFFileAttributes)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER OFString *path = URI.fileSystemRepresentation; uid_t uid = -1; gid_t gid = -1; OFStringEncoding encoding; if (owner == nil && group == nil) @throw [OFInvalidArgumentException exception]; encoding = [OFLocale encoding]; # ifdef OF_HAVE_THREADS [passwdMutex lock]; @try { # endif if (owner != nil) { struct passwd *passwd; if ((passwd = getpwnam([owner cStringWithEncoding: encoding])) == NULL) @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: errno]; uid = passwd->pw_uid; } if (group != nil) { struct group *group_; if ((group_ = getgrnam([group cStringWithEncoding: encoding])) == NULL) @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: errno]; gid = group_->gr_gid; } # ifdef OF_HAVE_THREADS } @finally { [passwdMutex unlock]; } # endif if (chown([path cStringWithEncoding: encoding], uid, gid) != 0) @throw [OFSetItemAttributesFailedException exceptionWithURI: URI attributes: attributes failedAttribute: attributeKey errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); OFEnumerator OF_GENERIC(OFFileAttributeKey) *keyEnumerator; OFEnumerator *objectEnumerator; OFFileAttributeKey key; id object; OFDate *lastAccessDate, *modificationDate; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; keyEnumerator = [attributes keyEnumerator]; objectEnumerator = [attributes objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { if ([key isEqual: OFFileModificationDate] || [key isEqual: OFFileLastAccessDate]) continue; else if ([key isEqual: OFFilePOSIXPermissions]) [self of_setPOSIXPermissions: object ofItemAtURI: URI attributes: attributes]; else if ([key isEqual: OFFileOwnerAccountName]) [self of_setOwnerAccountName: object andGroupOwnerAccountName: nil ofItemAtURI: URI attributeKey: key attributes: attributes]; else if ([key isEqual: OFFileGroupOwnerAccountName]) [self of_setOwnerAccountName: nil andGroupOwnerAccountName: object ofItemAtURI: URI attributeKey: key attributes: attributes]; else @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; } lastAccessDate = [attributes objectForKey: OFFileLastAccessDate]; modificationDate = [attributes objectForKey: OFFileModificationDate]; if (lastAccessDate != nil || modificationDate != nil) [self of_setLastAccessDate: lastAccessDate andModificationDate: modificationDate ofItemAtURI: URI attributes: attributes]; objc_autoreleasePoolPop(pool); } - (bool)fileExistsAtURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); Stat s; bool ret; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; if (statWrapper(URI.fileSystemRepresentation, &s) != 0) { objc_autoreleasePoolPop(pool); return false; } ret = S_ISREG(s.st_mode); objc_autoreleasePoolPop(pool); return ret; } - (bool)directoryExistsAtURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); Stat s; bool ret; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; if (statWrapper(URI.fileSystemRepresentation, &s) != 0) { objc_autoreleasePoolPop(pool); return false; } ret = S_ISDIR(s.st_mode); objc_autoreleasePoolPop(pool); return ret; } - (void)createDirectoryAtURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); OFString *path; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URI.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 exceptionWithURI: URI errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock; if ((lock = CreateDir( [path cStringWithEncoding: [OFLocale encoding]])) == 0) @throw [OFCreateDirectoryFailedException exceptionWithURI: URI errNo: lastError()]; UnLock(lock); #else if (mkdir([path cStringWithEncoding: [OFLocale encoding]], 0777) != 0) @throw [OFCreateDirectoryFailedException exceptionWithURI: URI errNo: errno]; #endif objc_autoreleasePoolPop(pool); } - (OFArray OF_GENERIC(OFURI *) *)contentsOfDirectoryAtURI: (OFURI *)URI { OFMutableArray *URIs = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *path; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URI.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) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: nil errNo: lastError()]; @try { do { OFString *file; if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0) continue; file = [[OFString alloc] initWithUTF16String: fd.cFileName]; @try { [URIs addObject: [URI URIByAppendingPathComponent: file]]; } @finally { [file release]; } } while (FindNextFileW(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: lastError()]; } @finally { FindClose(handle); } } else { OFStringEncoding encoding = [OFLocale encoding]; WIN32_FIND_DATA fd; if ((handle = FindFirstFileA( [path cStringWithEncoding: encoding], &fd)) == INVALID_HANDLE_VALUE) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: nil errNo: lastError()]; @try { do { OFString *file; if (strcmp(fd.cFileName, ".") == 0 || strcmp(fd.cFileName, "..") == 0) continue; file = [[OFString alloc] initWithCString: fd.cFileName encoding: encoding]; @try { [URIs addObject: [URI URIByAppendingPathComponent: file]]; } @finally { [file release]; } } while (FindNextFileA(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: lastError()]; } @finally { FindClose(handle); } } #elif defined(OF_AMIGAOS) OFStringEncoding encoding = [OFLocale encoding]; BPTR lock; if ((lock = Lock([path cStringWithEncoding: encoding], SHARED_LOCK)) == 0) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: nil errNo: lastError()]; @try { # ifdef OF_AMIGAOS4 struct ExamineData *ed; APTR context; if ((context = ObtainDirContextTags(EX_FileLockInput, lock, EX_DoCurrentDir, TRUE, EX_DataFields, EXF_NAME, TAG_END)) == NULL) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: nil errNo: lastError()]; @try { while ((ed = ExamineDir(context)) != NULL) { OFString *file = [[OFString alloc] initWithCString: ed->Name encoding: encoding]; @try { [URIs addObject: [URI URIByAppendingPathComponent: file]]; } @finally { [file release]; } } } @finally { ReleaseDirContext(context); } # else struct FileInfoBlock fib; if (!Examine(lock, &fib)) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: nil errNo: lastError()]; while (ExNext(lock, &fib)) { OFString *file = [[OFString alloc] initWithCString: fib.fib_FileName encoding: encoding]; @try { [URIs addObject: [URI URIByAppendingPathComponent: file]]; } @finally { [file release]; } } # endif if (IoErr() != ERROR_NO_MORE_ENTRIES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: lastError()]; } @finally { UnLock(lock); } #else OFStringEncoding encoding = [OFLocale encoding]; DIR *dir; if ((dir = opendir([path cStringWithEncoding: encoding])) == NULL) @throw [OFOpenItemFailedException exceptionWithURI: URI mode: nil errNo: errno]; # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) @try { [readdirMutex lock]; } @catch (id e) { |
︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 | if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue; file = [[OFString alloc] initWithCString: dirent->d_name encoding: encoding]; @try { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 1294 1295 1296 1297 1298 1299 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 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 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 | if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue; file = [[OFString alloc] initWithCString: dirent->d_name encoding: encoding]; @try { [URIs addObject: [URI URIByAppendingPathComponent: file]]; } @finally { [file release]; } } } @finally { closedir(dir); # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) [readdirMutex unlock]; # endif } #endif [URIs makeImmutable]; objc_autoreleasePoolPop(pool); return URIs; } - (void)removeItemAtURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); OFString *path; int error; Stat s; if (URI == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URI.fileSystemRepresentation; if ((error = lstatWrapper(path, &s)) != 0) @throw [OFRemoveItemFailedException exceptionWithURI: URI errNo: error]; if (S_ISDIR(s.st_mode)) { OFArray OF_GENERIC(OFURI *) *contents; @try { contents = [self contentsOfDirectoryAtURI: URI]; } @catch (id e) { /* * Only convert exceptions to * OFRemoveItemFailedException that have an errNo * property. This covers all I/O related exceptions * from the operations used to remove an item, all * others should be left as is. */ if ([e respondsToSelector: @selector(errNo)]) @throw [OFRemoveItemFailedException exceptionWithURI: URI errNo: [e errNo]]; @throw e; } for (OFURI *item in contents) { void *pool2 = objc_autoreleasePoolPush(); [self removeItemAtURI: 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 exceptionWithURI: URI 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 exceptionWithURI: URI errNo: errno]; #endif } #ifdef OF_AMIGAOS if (!DeleteFile([path cStringWithEncoding: [OFLocale encoding]])) @throw [OFRemoveItemFailedException exceptionWithURI: URI errNo: lastError()]; #endif objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS - (void)linkItemAtURI: (OFURI *)source toURI: (OFURI *)destination { void *pool = objc_autoreleasePoolPush(); OFString *sourcePath, *destinationPath; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; if (![source.scheme isEqual: _scheme] || ![destination.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; sourcePath = source.fileSystemRepresentation; destinationPath = destination.fileSystemRepresentation; # ifndef OF_WINDOWS OFStringEncoding encoding = [OFLocale encoding]; if (link([sourcePath cStringWithEncoding: encoding], [destinationPath cStringWithEncoding: encoding]) != 0) @throw [OFLinkItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: errno]; # else if (createHardLinkWFuncPtr == NULL) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (!createHardLinkWFuncPtr(destinationPath.UTF16String, sourcePath.UTF16String, NULL)) @throw [OFLinkItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: lastError()]; # endif objc_autoreleasePoolPop(pool); } #endif #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS - (void)createSymbolicLinkAtURI: (OFURI *)URI withDestinationPath: (OFString *)target { void *pool = objc_autoreleasePoolPush(); OFString *path; if (URI == nil || target == nil) @throw [OFInvalidArgumentException exception]; if (![URI.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URI.fileSystemRepresentation; # ifndef OF_WINDOWS OFStringEncoding encoding = [OFLocale encoding]; if (symlink([target cStringWithEncoding: encoding], [path cStringWithEncoding: encoding]) != 0) @throw [OFCreateSymbolicLinkFailedException exceptionWithURI: URI target: target errNo: errno]; # else if (createSymbolicLinkWFuncPtr == NULL) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (!createSymbolicLinkWFuncPtr(path.UTF16String, target.UTF16String, 0)) @throw [OFCreateSymbolicLinkFailedException exceptionWithURI: URI target: target errNo: lastError()]; # endif objc_autoreleasePoolPop(pool); } #endif - (bool)moveItemAtURI: (OFURI *)source toURI: (OFURI *)destination { void *pool; if (![source.scheme isEqual: _scheme] || ![destination.scheme isEqual: _scheme]) return false; if ([self fileExistsAtURI: destination]) @throw [OFMoveItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: EEXIST]; pool = objc_autoreleasePoolPush(); #ifdef OF_AMIGAOS OFStringEncoding encoding = [OFLocale encoding]; if (!Rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding])) @throw [OFMoveItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: lastError()]; #else int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wrename(source.fileSystemRepresentation.UTF16String, destination.fileSystemRepresentation.UTF16String); |
︙ | ︙ | |||
1460 1461 1462 1463 1464 1465 1466 | cStringWithEncoding: encoding]); # ifdef OF_WINDOWS } # endif if (status != 0) @throw [OFMoveItemFailedException | | | | 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 | cStringWithEncoding: encoding]); # ifdef OF_WINDOWS } # endif if (status != 0) @throw [OFMoveItemFailedException exceptionWithSourceURI: source destinationURI: destination errNo: errno]; #endif objc_autoreleasePoolPop(pool); return true; } @end |
Modified src/OFHMAC.h from [618167fc85] to [2d8e8879fb].
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | @property (readonly, nonatomic) bool allowsSwappableMemory; /** * @brief A buffer containing the HMAC. * * The size of the buffer depends on the hash used. The buffer is part of the * receiver's memory pool. */ @property (readonly, nonatomic) const unsigned char *digest OF_RETURNS_INNER_POINTER; /** * @brief The size of the digest. */ | > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | @property (readonly, nonatomic) bool allowsSwappableMemory; /** * @brief A buffer containing the HMAC. * * The size of the buffer depends on the hash used. The buffer is part of the * receiver's memory pool. * * @throw OFHashNotCalculatedException The HMAC hasn't been calculated yet */ @property (readonly, nonatomic) const unsigned char *digest OF_RETURNS_INNER_POINTER; /** * @brief The size of the digest. */ |
︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | - (void)setKey: (const void *)key length: (size_t)length; /** * @brief Adds a buffer to the HMAC to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; /** * @brief Performs the final calculation of the HMAC. */ - (void)calculate; /** * @brief Resets the HMAC so that it can be calculated for a new message. * * @note This does not reset the key so that a new HMAC with the same key can | > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | - (void)setKey: (const void *)key length: (size_t)length; /** * @brief Adds a buffer to the HMAC to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer * @throw OFHashAlreadyCalculatedException The HMAC has already been calculated */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; /** * @brief Performs the final calculation of the HMAC. * * @throw OFHashAlreadyCalculatedException The HMAC has already been calculated */ - (void)calculate; /** * @brief Resets the HMAC so that it can be calculated for a new message. * * @note This does not reset the key so that a new HMAC with the same key can |
︙ | ︙ |
Modified src/OFHTTPClient.h from [4532ba7b26] to [d5da950339].
︙ | ︙ | |||
24 25 26 27 28 29 30 | @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFHTTPClient; @class OFHTTPRequest; @class OFHTTPResponse; @class OFStream; @class OFTCPSocket; @class OFTLSStream; | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFHTTPClient; @class OFHTTPRequest; @class OFHTTPResponse; @class OFStream; @class OFTCPSocket; @class OFTLSStream; @class OFURI; /** * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A delegate for OFHTTPClient. */ @protocol OFHTTPClientDelegate <OFObject> |
︙ | ︙ | |||
115 116 117 118 119 120 121 | * to detect a redirect. * * This callback will only be called if the OFHTTPClient will follow a * redirect. If the maximum number of redirects has been reached already, this * callback will not be called. * * @param client The OFHTTPClient which wants to follow a redirect | | | | | | | | | | | 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 | * to detect a redirect. * * This callback will only be called if the OFHTTPClient will follow a * redirect. If the maximum number of redirects has been reached already, this * callback will not be called. * * @param client The OFHTTPClient which wants to follow a redirect * @param URI The URI to which it will follow a redirect * @param statusCode The status code for the redirection * @param request The request for which the OFHTTPClient wants to redirect. * You are allowed to change the request's headers from this * callback and they will be used when following the redirect * (e.g. to set the cookies for the new URI), however, keep in * mind that this will change the request you originally passed. * @param response The response indicating the redirect * @return A boolean whether the OFHTTPClient should follow the redirect */ - (bool)client: (OFHTTPClient *)client shouldFollowRedirectToURI: (OFURI *)URI statusCode: (short)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response; @end /** * @class OFHTTPClient OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A class for performing HTTP requests. */ OF_SUBCLASSING_RESTRICTED @interface OFHTTPClient: OFObject { #ifdef OF_HTTP_CLIENT_M @public #endif OFObject <OFHTTPClientDelegate> *_Nullable _delegate; bool _allowsInsecureRedirects, _inProgress; OFStream *_Nullable _stream; OFURI *_Nullable _lastURI; bool _lastWasHEAD; OFHTTPResponse *_Nullable _lastResponse; } /** * @brief The delegate of the HTTP request. */ |
︙ | ︙ | |||
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 | * * @note You must not change the delegate while a synchronous request is * running! If you want to change the delegate during the request, * perform an asynchronous request instead! * * @param request The request to perform * @return The OFHTTPResponse for the request */ - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request; /** * @brief Synchronously performs the specified HTTP request. * * @note You must not change the delegate while a synchronous request is * running! If you want to change the delegate during the request, * perform an asynchronous request instead! * * @param request The request to perform * @param redirects The maximum number of redirects after which no further * attempt is done to follow the redirect, but instead the * redirect is treated as an OFHTTPResponse * @return The OFHTTPResponse for the request */ - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; /** * @brief Asynchronously performs the specified HTTP request. * * @param request The request to perform */ - (void)asyncPerformRequest: (OFHTTPRequest *)request; /** * @brief Asynchronously performs the specified HTTP request. * * @param request The request to perform * @param redirects The maximum number of redirects after which no further * attempt is done to follow the redirect, but instead the * redirect is treated as an OFHTTPResponse */ - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; /** * @brief Closes connections that are still open due to keep-alive. */ - (void)close; @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > > | 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 | * * @note You must not change the delegate while a synchronous request is * running! If you want to change the delegate during the request, * perform an asynchronous request instead! * * @param request The request to perform * @return The OFHTTPResponse for the request * @throw OFHTTPRequestFailedException The HTTP request failed * @throw OFInvalidServerResponseException The server sent an invalid response * @throw OFUnsupportedVersionException The server responded in an unsupported * version * @throw OFAlreadyConnectedException The client is already performing a request */ - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request; /** * @brief Synchronously performs the specified HTTP request. * * @note You must not change the delegate while a synchronous request is * running! If you want to change the delegate during the request, * perform an asynchronous request instead! * * @param request The request to perform * @param redirects The maximum number of redirects after which no further * attempt is done to follow the redirect, but instead the * redirect is treated as an OFHTTPResponse * @return The OFHTTPResponse for the request * @throw OFHTTPRequestFailedException The HTTP request failed * @throw OFInvalidServerResponseException The server sent an invalid response * @throw OFUnsupportedVersionException The server responded in an unsupported * version * @throw OFAlreadyConnectedException The client is already performing a request */ - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; /** * @brief Asynchronously performs the specified HTTP request. * * @param request The request to perform * @throw OFAlreadyConnectedException The client is already performing a request */ - (void)asyncPerformRequest: (OFHTTPRequest *)request; /** * @brief Asynchronously performs the specified HTTP request. * * @param request The request to perform * @param redirects The maximum number of redirects after which no further * attempt is done to follow the redirect, but instead the * redirect is treated as an OFHTTPResponse * @throw OFAlreadyConnectedException The client is already performing a request */ - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; /** * @brief Closes connections that are still open due to keep-alive. */ - (void)close; @end OF_ASSUME_NONNULL_END |
Modified src/OFHTTPClient.m from [74f8b0c30d] to [e887f99bf5].
︙ | ︙ | |||
9 10 11 12 13 14 15 | * * 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. */ | | | | | 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 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #define OF_HTTP_CLIENT_M #include "config.h" #include <errno.h> #include <string.h> #import "OFHTTPClient.h" #import "OFData.h" #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFRunLoop.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFTLSStream.h" #import "OFURI.h" #import "OFAlreadyConnectedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerResponseException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFUnsupportedVersionException.h" |
︙ | ︙ | |||
113 114 115 116 117 118 119 | @end static OFString * constructRequestString(OFHTTPRequest *request) { void *pool = objc_autoreleasePoolPush(); OFHTTPRequestMethod method = request.method; | | | | | | | | | | > | 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 | @end static OFString * constructRequestString(OFHTTPRequest *request) { void *pool = objc_autoreleasePoolPush(); OFHTTPRequestMethod method = request.method; OFURI *URI = request.URI; OFString *path; OFString *user = URI.user, *password = URI.password; OFMutableString *requestString; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; bool hasContentLength, chunked; OFEnumerator OF_GENERIC(OFString *) *keyEnumerator, *objectEnumerator; OFString *key, *object; if (URI.path.length > 0) path = URI.percentEncodedPath; else path = @"/"; requestString = [OFMutableString stringWithFormat: @"%s %@", OFHTTPRequestMethodName(method), path]; if (URI.query != nil) { [requestString appendString: @"?"]; [requestString appendString: URI.percentEncodedQuery]; } [requestString appendString: @" HTTP/"]; [requestString appendString: request.protocolVersionString]; [requestString appendString: @"\r\n"]; headers = [[request.headers mutableCopy] autorelease]; if (headers == nil) headers = [OFMutableDictionary dictionary]; if ([headers objectForKey: @"Host"] == nil) { OFNumber *port = URI.port; if (port != nil) { OFString *host = [OFString stringWithFormat: @"%@:%@", URI.percentEncodedHost, port]; [headers setObject: host forKey: @"Host"]; } else [headers setObject: URI.percentEncodedHost forKey: @"Host"]; } if ((user.length > 0 || password.length > 0) && [headers objectForKey: @"Authorization"] == nil) { OFMutableData *authorizationData = [OFMutableData data]; OFString *authorization; |
︙ | ︙ | |||
294 295 296 297 298 299 300 | didPerformRequest: _request response: nil exception: exception]; } - (void)createResponseWithStreamOrThrow: (OFStream *)stream { | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | didPerformRequest: _request response: nil exception: exception]; } - (void)createResponseWithStreamOrThrow: (OFStream *)stream { OFURI *URI = _request.URI; OFHTTPClientResponse *response; OFString *connectionHeader; bool keepAlive; OFString *location; id exception; response = [[[OFHTTPClientResponse alloc] initWithStream: stream] |
︙ | ︙ | |||
325 326 327 328 329 330 331 | keepAlive = false; } if (keepAlive) { response.of_keepAlive = true; _client->_stream = [stream retain]; | | | | | < | | | | | | > | | | | 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 | keepAlive = false; } if (keepAlive) { response.of_keepAlive = true; _client->_stream = [stream retain]; _client->_lastURI = [URI copy]; _client->_lastWasHEAD = (_request.method == OFHTTPRequestMethodHead); _client->_lastResponse = [response retain]; } if (_redirects > 0 && (_status == 301 || _status == 302 || _status == 303 || _status == 307) && (location = [_serverHeaders objectForKey: @"Location"]) != nil) { bool follow = true; OFURI *newURI; OFString *newURIScheme; newURI = [OFURI URIWithString: location relativeToURI: URI]; newURIScheme = newURI.scheme; if ([newURIScheme caseInsensitiveCompare: @"http"] != OFOrderedSame && [newURIScheme caseInsensitiveCompare: @"https"] != OFOrderedSame) follow = false; if (!_client->_allowsInsecureRedirects && [URI.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame && [newURIScheme caseInsensitiveCompare: @"http"] == OFOrderedSame) follow = false; if (follow && [_client->_delegate respondsToSelector: @selector(client:shouldFollowRedirectToURI:statusCode: request:response:)]) follow = [_client->_delegate client: _client shouldFollowRedirectToURI: newURI 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]; OFMutableDictionary *newHeaders = [[headers mutableCopy] autorelease]; if (![newURI.host isEqual: URI.host]) [newHeaders removeObjectForKey: @"Host"]; /* * 303 means the request should be converted to a GET * request before redirection. This also means stripping * the entity of the request. */ |
︙ | ︙ | |||
399 400 401 402 403 404 405 | [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; newRequest.method = OFHTTPRequestMethodGet; } | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; newRequest.method = OFHTTPRequestMethodGet; } newRequest.URI = newURI; newRequest.headers = newHeaders; _client->_inProgress = false; [_client asyncPerformRequest: newRequest redirects: _redirects - 1]; return; |
︙ | ︙ | |||
453 454 455 456 457 458 459 | if (line == nil) { [self closeAndReconnect]; return false; } if (![line hasPrefix: @"HTTP/"] || line.length < 9 || [line characterAtIndex: 8] != ' ') | | | | | | | 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 | if (line == nil) { [self closeAndReconnect]; return false; } if (![line hasPrefix: @"HTTP/"] || line.length < 9 || [line characterAtIndex: 8] != ' ') @throw [OFInvalidServerResponseException exception]; _version = [[line substringWithRange: OFMakeRange(5, 3)] copy]; if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"]) @throw [OFUnsupportedVersionException exceptionWithVersion: _version]; status = [line substringWithRange: OFMakeRange(9, 3)].longLongValue; if (status < 0 || status > 599) @throw [OFInvalidServerResponseException exception]; _status = (short)status; return true; } - (bool)handleServerHeader: (OFString *)line stream: (OFStream *)stream { OFString *key, *value, *old; const char *lineC, *tmp; char *keyC; if (line == nil) @throw [OFInvalidServerResponseException exception]; if (line.length == 0) { [_serverHeaders makeImmutable]; if ([_client->_delegate respondsToSelector: @selector(client: didReceiveHeaders:statusCode:request:)]) [_client->_delegate client: _client |
︙ | ︙ | |||
501 502 503 504 505 506 507 | return false; } lineC = line.UTF8String; if ((tmp = strchr(lineC, ':')) == NULL) | | | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | return false; } lineC = line.UTF8String; if ((tmp = strchr(lineC, ':')) == NULL) @throw [OFInvalidServerResponseException exception]; keyC = OFAllocMemory(tmp - lineC + 1, 1); memcpy(keyC, lineC, tmp - lineC); keyC[tmp - lineC] = '\0'; normalizeKey(keyC); @try { |
︙ | ︙ | |||
540 541 542 543 544 545 546 | exception: (id)exception { bool ret; if (exception != nil) { if ([exception isKindOfClass: [OFInvalidEncodingException class]]) | | > | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | exception: (id)exception { bool ret; if (exception != nil) { if ([exception isKindOfClass: [OFInvalidEncodingException class]]) exception = [OFInvalidServerResponseException exception]; [self raiseException: exception]; return false; } @try { if (_firstLine) { |
︙ | ︙ | |||
642 643 644 645 646 647 648 | if ([_client->_delegate respondsToSelector: @selector(client:didCreateTCPSocket:request:)]) [_client->_delegate client: _client didCreateTCPSocket: sock request: _request]; | | | | | 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 | if ([_client->_delegate respondsToSelector: @selector(client:didCreateTCPSocket:request:)]) [_client->_delegate client: _client didCreateTCPSocket: sock request: _request]; if ([_request.URI.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame) { OFTLSStream *stream; @try { stream = [OFTLSStream streamWithStream: sock]; } @catch (OFNotImplementedException *e) { [self raiseException: [OFUnsupportedProtocolException exceptionWithURI: _request.URI]]; return; } if ([_client->_delegate respondsToSelector: @selector(client:didCreateTLSStream:request:)]) [_client->_delegate client: _client didCreateTLSStream: stream request: _request]; stream.delegate = self; [stream asyncPerformClientHandshakeWithHost: _request.URI.host]; } else { sock.delegate = self; [self performSelector: @selector(handleStream:) withObject: sock afterDelay: 0]; } } |
︙ | ︙ | |||
686 687 688 689 690 691 692 | [self performSelector: @selector(handleStream:) withObject: stream afterDelay: 0]; } - (void)start { | | | | | | | | | | | | | | | | 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 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | [self performSelector: @selector(handleStream:) withObject: stream afterDelay: 0]; } - (void)start { OFURI *URI = _request.URI; OFStream *stream; /* Can we reuse the last socket? */ if (_client->_stream != nil && !_client->_stream.atEndOfStream && [_client->_lastURI.scheme isEqual: URI.scheme] && [_client->_lastURI.host isEqual: URI.host] && (_client->_lastURI.port == URI.port || [_client->_lastURI.port isEqual: URI.port]) && (_client->_lastWasHEAD || _client->_lastResponse.atEndOfStream)) { /* * Set _stream to nil, so that in case of an error it won't be * reused. If everything is successful, we set _stream again * at the end. */ stream = [_client->_stream autorelease]; _client->_stream = nil; [_client->_lastURI release]; _client->_lastURI = nil; [_client->_lastResponse release]; _client->_lastResponse = nil; stream.delegate = self; [self performSelector: @selector(handleStream:) withObject: stream afterDelay: 0]; } else [self closeAndReconnect]; } - (void)closeAndReconnect { @try { OFURI *URI = _request.URI; OFTCPSocket *sock; uint16_t port; OFNumber *URIPort; [_client close]; sock = [OFTCPSocket socket]; if ([URI.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame) port = 443; else port = 80; URIPort = URI.port; if (URIPort != nil) port = URIPort.unsignedShortValue; sock.delegate = self; [sock asyncConnectToHost: URI.host port: port]; } @catch (id e) { [self raiseException: e]; } } @end @implementation OFHTTPClientRequestBodyStream |
︙ | ︙ | |||
897 898 899 900 901 902 903 | _chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; contentLength = [headers objectForKey: @"Content-Length"]; if (contentLength != nil) { if (_chunked || contentLength.length == 0) | | | | 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 | _chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; contentLength = [headers objectForKey: @"Content-Length"]; if (contentLength != nil) { if (_chunked || contentLength.length == 0) @throw [OFInvalidServerResponseException exception]; _hasContentLength = true; @try { unsigned long long toRead = contentLength.unsignedLongLongValue; if (toRead > LLONG_MAX) @throw [OFOutOfRangeException exception]; _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerResponseException exception]; } } } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { if (_stream == nil) |
︙ | ︙ | |||
956 957 958 959 960 961 962 | if (_toRead == -2) { char tmp[2]; switch ([_stream readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') | | | | | 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 | if (_toRead == -2) { char tmp[2]; switch ([_stream readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') @throw [OFInvalidServerResponseException exception]; case 1: _toRead++; if (tmp[0] != '\r') @throw [OFInvalidServerResponseException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead == -1) { char tmp; if ([_stream readIntoBuffer: &tmp length: 1] == 1) { _toRead++; if (tmp != '\n') @throw [OFInvalidServerResponseException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; |
︙ | ︙ | |||
1002 1003 1004 1005 1006 1007 1008 | void *pool = objc_autoreleasePoolPush(); OFString *line; size_t pos; @try { line = [_stream tryReadLine]; } @catch (OFInvalidEncodingException *e) { | | | | | 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 1041 1042 1043 1044 1045 1046 1047 1048 1049 | void *pool = objc_autoreleasePoolPush(); OFString *line; size_t pos; @try { line = [_stream tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidServerResponseException exception]; } if (line == nil) return 0; pos = [line rangeOfString: @";"].location; if (pos != OFNotFound) line = [line substringToIndex: pos]; if (line.length < 1) { /* * We have read the empty string because the stream is * at end of stream. */ if (_stream.atEndOfStream && pos == OFNotFound) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidServerResponseException exception]; } @try { unsigned long long toRead = [line unsignedLongLongValueWithBase: 16]; if (toRead > LLONG_MAX) @throw [OFOutOfRangeException exception]; _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerResponseException exception]; } if (_toRead == 0) { _setAtEndOfStream = true; _toRead = -2; } |
︙ | ︙ | |||
1196 1197 1198 1199 1200 1201 1202 | @selector(client:didReceiveHeaders:statusCode:request:)]) [_delegate client: client didReceiveHeaders: headers statusCode: statusCode request: request]; } | | | | | | | | | | | | | | 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 | @selector(client:didReceiveHeaders:statusCode:request:)]) [_delegate client: client didReceiveHeaders: headers statusCode: statusCode request: request]; } - (bool)client: (OFHTTPClient *)client shouldFollowRedirectToURI: (OFURI *)URI statusCode: (short)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { if ([_delegate respondsToSelector: @selector( client:shouldFollowRedirectToURI:statusCode:request:response:)]) return [_delegate client: client shouldFollowRedirectToURI: URI statusCode: statusCode request: request response: response]; else return defaultShouldFollow(request.method, statusCode); } @end @implementation OFHTTPClient @synthesize delegate = _delegate; |
︙ | ︙ | |||
1261 1262 1263 1264 1265 1266 1267 | [self asyncPerformRequest: request redirects: defaultRedirects]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); | | | | < | | | 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 1296 1297 1298 1299 1300 1301 | [self asyncPerformRequest: request redirects: defaultRedirects]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFURI *URI = request.URI; OFString *scheme = URI.scheme; if ([scheme caseInsensitiveCompare: @"http"] != OFOrderedSame && [scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) @throw [OFUnsupportedProtocolException exceptionWithURI: URI]; if (_inProgress) @throw [OFAlreadyConnectedException exception]; _inProgress = true; [[[[OFHTTPClientRequestHandler alloc] initWithClient: self request: request redirects: redirects] autorelease] start]; objc_autoreleasePoolPop(pool); } - (void)close { [_stream release]; _stream = nil; [_lastURI release]; _lastURI = nil; [_lastResponse release]; _lastResponse = nil; } @end |
Modified src/OFHTTPCookie.h from [c915720e1d] to [ff53970b1e].
︙ | ︙ | |||
18 19 20 21 22 23 24 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); | | > < | 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 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFURI; /** * @class OFHTTPCookie OFHTTPCookie.h ObjFW/OFHTTPCookie.h * * @brief A class for storing and manipulating HTTP cookies. */ OF_SUBCLASSING_RESTRICTED @interface OFHTTPCookie: OFObject <OFCopying> { OFString *_name, *_value, *_domain, *_path; OFDate *_Nullable _expires; bool _secure, _HTTPOnly; OFMutableArray OF_GENERIC(OFString *) *_extensions; } /** * @brief The name of the cookie. */ @property (copy, nonatomic) OFString *name; |
︙ | ︙ | |||
76 77 78 79 80 81 82 | /** * @brief An array of other attributes. */ @property (readonly, nonatomic) OFMutableArray OF_GENERIC(OFString *) *extensions; /** | | | > > | | 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 | /** * @brief An array of other attributes. */ @property (readonly, nonatomic) OFMutableArray OF_GENERIC(OFString *) *extensions; /** * @brief Parses the specified response header fields for the specified URI and * returns an array of cookies. * * @param headerFields The response header fields to parse * @param URI The URI for the response header fields to parse * @return An array of cookies * @throw OFInvalidFormatException The specified response header has an invalid * format */ + (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesWithResponseHeaderFields: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields forURI: (OFURI *)URI; /** * @brief Returns the request header fields for the specified cookies. * * @param cookies The cookies to return the request header fields for * @return The request header fields for the specified cookies */ |
︙ | ︙ |
Modified src/OFHTTPCookie.m from [30659cca3c] to [a7d6a07918].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "config.h" #import "OFHTTPCookie.h" #import "OFArray.h" #import "OFDate.h" #import "OFDictionary.h" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include "config.h" #import "OFHTTPCookie.h" #import "OFArray.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFURI.h" #import "OFInvalidFormatException.h" static void handleAttribute(OFHTTPCookie *cookie, OFString *name, OFString *value) { OFString *lowercaseName = name.lowercaseString; |
︙ | ︙ | |||
58 59 60 61 62 63 64 | @implementation OFHTTPCookie @synthesize name = _name, value = _value, domain = _domain, path = _path; @synthesize expires = _expires, secure = _secure, HTTPOnly = _HTTPOnly; @synthesize extensions = _extensions; + (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesWithResponseHeaderFields: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | @implementation OFHTTPCookie @synthesize name = _name, value = _value, domain = _domain, path = _path; @synthesize expires = _expires, secure = _secure, HTTPOnly = _HTTPOnly; @synthesize extensions = _extensions; + (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesWithResponseHeaderFields: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields forURI: (OFURI *)URI { OFMutableArray OF_GENERIC(OFHTTPCookie *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *string = [headerFields objectForKey: @"Set-Cookie"]; OFString *domain = URI.host; const OFUnichar *characters = string.characters; size_t length = string.length, last = 0; enum { statePreName, stateName, stateExpectValue, stateValue, |
︙ | ︙ | |||
91 92 93 94 95 96 97 | last = i; i--; } break; case stateName: if (characters[i] == '=') { name = [string substringWithRange: | | | | | 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 | last = i; i--; } break; case stateName: if (characters[i] == '=') { name = [string substringWithRange: OFMakeRange(last, i - last)]; state = stateExpectValue; } break; case stateExpectValue: if (characters[i] == '"') { state = stateQuotedValue; last = i + 1; } else { state = stateValue; last = i; } i--; break; case stateValue: if (characters[i] == ';' || characters[i] == ',') { value = [string substringWithRange: OFMakeRange(last, i - last)]; [ret addObject: [OFHTTPCookie cookieWithName: name value: value domain: domain]]; state = (characters[i] == ';' ? statePreAttrName : statePreName); } break; case stateQuotedValue: if (characters[i] == '"') { value = [string substringWithRange: OFMakeRange(last, i - last)]; [ret addObject: [OFHTTPCookie cookieWithName: name value: value domain: domain]]; state = statePostQuotedValue; } |
︙ | ︙ | |||
151 152 153 154 155 156 157 | last = i; i--; } break; case stateAttrName: if (characters[i] == '=') { name = [string substringWithRange: | | | | | 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 | last = i; i--; } break; case stateAttrName: if (characters[i] == '=') { name = [string substringWithRange: OFMakeRange(last, i - last)]; state = stateAttrValue; last = i + 1; } else if (characters[i] == ';' || characters[i] == ',') { name = [string substringWithRange: OFMakeRange(last, i - last)]; handleAttribute(ret.lastObject, name, nil); state = (characters[i] == ';' ? statePreAttrName : statePreName); } break; case stateAttrValue: if (characters[i] == ';' || characters[i] == ',') { value = [string substringWithRange: OFMakeRange(last, i - last)]; /* * Expires often contains a comma, even though * the comma is used as a separator for * concatenating headers as per RFC 2616, * meaning RFC 6265 contradicts RFC 2616. * Solve this by special casing this. |
︙ | ︙ | |||
211 212 213 214 215 216 217 | break; case stateName: case stateQuotedValue: @throw [OFInvalidFormatException exception]; break; case stateValue: value = [string substringWithRange: | | | | | 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 | break; case stateName: case stateQuotedValue: @throw [OFInvalidFormatException exception]; break; case stateValue: value = [string substringWithRange: OFMakeRange(last, length - last)]; [ret addObject: [OFHTTPCookie cookieWithName: name value: value domain: domain]]; break; /* We end up here if the cookie is just foo= */ case stateExpectValue: [ret addObject: [OFHTTPCookie cookieWithName: name value: @"" domain: domain]]; break; case stateAttrName: if (last != length) { name = [string substringWithRange: OFMakeRange(last, length - last)]; handleAttribute(ret.lastObject, name, nil); } break; case stateAttrValue: value = [string substringWithRange: OFMakeRange(last, length - last)]; handleAttribute(ret.lastObject, name, value); break; } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
367 368 369 370 371 372 373 | OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _value.hash); OFHashAddHash(&hash, _domain.hash); OFHashAddHash(&hash, _path.hash); OFHashAddHash(&hash, _expires.hash); | | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _value.hash); OFHashAddHash(&hash, _domain.hash); OFHashAddHash(&hash, _path.hash); OFHashAddHash(&hash, _expires.hash); OFHashAddByte(&hash, _secure); OFHashAddByte(&hash, _HTTPOnly); OFHashAddHash(&hash, _extensions.hash); OFHashFinalize(&hash); return hash; } - (id)copy |
︙ | ︙ |
Modified src/OFHTTPCookieManager.h from [776c67cc36] to [3cc0432376].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFHTTPCookie; @class OFMutableArray OF_GENERIC(ObjectType); | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFHTTPCookie; @class OFMutableArray OF_GENERIC(ObjectType); @class OFURI; /** * @class OFHTTPCookieManager OFHTTPCookieManager.h ObjFW/OFHTTPCookieManager.h * * @brief A class for managing cookies for multiple domains. */ OF_SUBCLASSING_RESTRICTED |
︙ | ︙ | |||
42 43 44 45 46 47 48 | * @brief Create a new cookie manager. * * @return A new, autoreleased OFHTTPCookieManager */ + (instancetype)manager; /** | | | | | | | | | | | | 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 | * @brief Create a new cookie manager. * * @return A new, autoreleased OFHTTPCookieManager */ + (instancetype)manager; /** * @brief Adds the specified cookie for the specified URI. * * @warning This modifies the cookie (e.g. it sets the domain if it is unset)! * If you do not want this, pass a copy! * * @param cookie The cookie to add to the manager * @param URI The URI for which the cookie should be added */ - (void)addCookie: (OFHTTPCookie *)cookie forURI: (OFURI *)URI; /** * @brief Adds the specified cookies for the specified URI. * * @warning This modifies the cookies (e.g. it sets the domain if it is unset)! * If you do not want this, pass copies! * * @param cookies An array of cookies to add to the manager * @param URI The URI for which the cookies should be added */ - (void)addCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies forURI: (OFURI *)URI; /** * @brief Returns the cookies for the specified URI. * * @param URI The URI for which the cookies should be returned * @return The cookies for the specified URI */ - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesForURI: (OFURI *)URI; /** * @brief Purges all expired cookies. */ - (void)purgeExpiredCookies; @end OF_ASSUME_NONNULL_END |
Modified src/OFHTTPCookieManager.m from [ab6e7fb16a] to [1dd74fe07e].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "config.h" #import "OFHTTPCookieManager.h" #import "OFArray.h" #import "OFDate.h" #import "OFHTTPCookie.h" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include "config.h" #import "OFHTTPCookieManager.h" #import "OFArray.h" #import "OFDate.h" #import "OFHTTPCookie.h" #import "OFURI.h" @implementation OFHTTPCookieManager + (instancetype)manager { return [[[self alloc] init] autorelease]; } |
︙ | ︙ | |||
49 50 51 52 53 54 55 | } - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies { return [[_cookies copy] autorelease]; } | | | | | | | | | 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 | } - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies { return [[_cookies copy] autorelease]; } - (void)addCookie: (OFHTTPCookie *)cookie forURI: (OFURI *)URI { void *pool = objc_autoreleasePoolPush(); OFString *cookieDomain, *URIHost; size_t i; if (![cookie.path hasPrefix: @"/"]) cookie.path = @"/"; if (cookie.secure && [URI.scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) { objc_autoreleasePoolPop(pool); return; } cookieDomain = cookie.domain.lowercaseString; cookie.domain = cookieDomain; URIHost = URI.host.lowercaseString; if (![cookieDomain isEqual: URIHost]) { URIHost = [@"." stringByAppendingString: URIHost]; if (![cookieDomain hasSuffix: URIHost]) { objc_autoreleasePoolPop(pool); return; } } i = 0; for (OFHTTPCookie *iter in _cookies) { |
︙ | ︙ | |||
96 97 98 99 100 101 102 | [_cookies addObject: cookie]; objc_autoreleasePoolPop(pool); } - (void)addCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies | | | | | | | | | | | | | | 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 | [_cookies addObject: cookie]; objc_autoreleasePoolPop(pool); } - (void)addCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies forURI: (OFURI *)URI { for (OFHTTPCookie *cookie in cookies) [self addCookie: cookie forURI: URI]; } - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesForURI: (OFURI *)URI { OFMutableArray *ret = [OFMutableArray array]; for (OFHTTPCookie *cookie in _cookies) { void *pool; OFDate *expires; OFString *cookieDomain, *URIHost, *cookiePath, *URIPath; bool match; expires = cookie.expires; if (expires != nil && expires.timeIntervalSinceNow <= 0) continue; if (cookie.secure && [URI.scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) continue; pool = objc_autoreleasePoolPush(); cookieDomain = cookie.domain.lowercaseString; URIHost = URI.host.lowercaseString; if ([cookieDomain hasPrefix: @"."]) { if ([URIHost hasSuffix: cookieDomain]) match = true; else { cookieDomain = [cookieDomain substringFromIndex: 1]; match = [cookieDomain isEqual: URIHost]; } } else match = [cookieDomain isEqual: URIHost]; if (!match) { objc_autoreleasePoolPop(pool); continue; } cookiePath = cookie.path; URIPath = URI.path; if (![cookiePath isEqual: @"/"]) { if ([cookiePath isEqual: URIPath]) match = true; else { if (![cookiePath hasSuffix: @"/"]) cookiePath = [cookiePath stringByAppendingString: @"/"]; match = [URIPath hasPrefix: cookiePath]; } if (!match) { objc_autoreleasePoolPop(pool); continue; } } |
︙ | ︙ |
Modified src/OFHTTPRequest.h from [cc3f0d316f] to [1278addd47].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #import "OFObject.h" #import "OFSocket.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #import "OFObject.h" #import "OFSocket.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN @class OFURI; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFData; @class OFString; /** @file */ /** |
︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 | } OFHTTPRequestProtocolVersion; /** * @class OFHTTPRequest OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief A class for storing HTTP requests. */ @interface OFHTTPRequest: OFObject <OFCopying> { | > | < | | > > > > > > > > | 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 | } OFHTTPRequestProtocolVersion; /** * @class OFHTTPRequest OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief A class for storing HTTP requests. */ OF_SUBCLASSING_RESTRICTED @interface OFHTTPRequest: OFObject <OFCopying> { OFURI *_URI; OFHTTPRequestMethod _method; OFHTTPRequestProtocolVersion _protocolVersion; OFDictionary OF_GENERIC(OFString *, OFString *) *_Nullable _headers; OFSocketAddress _remoteAddress; bool _hasRemoteAddress; } /** * @brief The URI of the HTTP request. */ @property (copy, nonatomic) OFURI *URI; /** * @brief The protocol version of the HTTP request. * * @throw OFUnsupportedVersionException The specified version cannot be set * because it is not supported */ @property (nonatomic) OFHTTPRequestProtocolVersion protocolVersion; /** * @brief The protocol version of the HTTP request as a string. * * @throw OFUnsupportedVersionException The specified version cannot be set * because it is not supported * @throw OFInvalidFormatException The specified version cannot be set because * it is not in a valid format */ @property (copy, nonatomic) OFString *protocolVersionString; /** * @brief The request method of the HTTP request. */ @property (nonatomic) OFHTTPRequestMethod method; |
︙ | ︙ | |||
106 107 108 109 110 111 112 | * @brief The remote address from which the request originates. * * @note The setter creates a copy of the remote address. */ @property OF_NULLABLE_PROPERTY (nonatomic) const OFSocketAddress *remoteAddress; /** | | | | | | | | 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 | * @brief The remote address from which the request originates. * * @note The setter creates a copy of the remote address. */ @property OF_NULLABLE_PROPERTY (nonatomic) const OFSocketAddress *remoteAddress; /** * @brief Creates a new OFHTTPRequest with the specified URI. * * @param URI The URI for the request * @return A new, autoreleased OFHTTPRequest */ + (instancetype)requestWithURI: (OFURI *)URI; /** * @brief Initializes an already allocated OFHTTPRequest with the specified URI. * * @param URI The URI for the request * @return An initialized OFHTTPRequest */ - (instancetype)initWithURI: (OFURI *)URI; - (instancetype)init OF_UNAVAILABLE; @end #ifdef __cplusplus extern "C" { #endif |
︙ | ︙ | |||
141 142 143 144 145 146 147 148 149 150 151 152 153 154 | OFHTTPRequestMethod method); /** * @brief Returns the request method for the specified string. * * @param string The string for which the request method should be returned * @return The request method for the specified string */ extern OFHTTPRequestMethod OFHTTPRequestMethodParseName(OFString *string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END | > > | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | OFHTTPRequestMethod method); /** * @brief Returns the request method for the specified string. * * @param string The string for which the request method should be returned * @return The request method for the specified string * @throw OFInvalidFormatException The specified string is not a valid HTTP * request method */ extern OFHTTPRequestMethod OFHTTPRequestMethodParseName(OFString *string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFHTTPRequest.m from [723c374a89] to [c85955ea02].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "config.h" #include <string.h> #import "OFHTTPRequest.h" #import "OFString.h" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include "config.h" #include <string.h> #import "OFHTTPRequest.h" #import "OFString.h" #import "OFURI.h" #import "OFDictionary.h" #import "OFData.h" #import "OFArray.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" |
︙ | ︙ | |||
70 71 72 73 74 75 76 | if ([string isEqual: @"DELETE"]) return OFHTTPRequestMethodDelete; if ([string isEqual: @"TRACE"]) return OFHTTPRequestMethodTrace; if ([string isEqual: @"CONNECT"]) return OFHTTPRequestMethodConnect; | | | | | | | | | 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 | if ([string isEqual: @"DELETE"]) return OFHTTPRequestMethodDelete; if ([string isEqual: @"TRACE"]) return OFHTTPRequestMethodTrace; if ([string isEqual: @"CONNECT"]) return OFHTTPRequestMethodConnect; @throw [OFInvalidFormatException exception]; } @implementation OFHTTPRequest @synthesize URI = _URI, method = _method, headers = _headers; + (instancetype)requestWithURI: (OFURI *)URI { return [[[self alloc] initWithURI: URI] autorelease]; } - (instancetype)initWithURI: (OFURI *)URI { self = [super init]; @try { _URI = [URI copy]; _method = OFHTTPRequestMethodGet; _protocolVersion.major = 1; _protocolVersion.minor = 1; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_URI release]; [_headers release]; [super dealloc]; } - (void)setRemoteAddress: (const OFSocketAddress *)remoteAddress { |
︙ | ︙ | |||
129 130 131 132 133 134 135 | return &_remoteAddress; return NULL; } - (id)copy { | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | return &_remoteAddress; return NULL; } - (id)copy { OFHTTPRequest *copy = [[OFHTTPRequest alloc] initWithURI: _URI]; @try { copy->_method = _method; copy->_protocolVersion = _protocolVersion; copy.headers = _headers; copy.remoteAddress = self.remoteAddress; } @catch (id e) { |
︙ | ︙ | |||
159 160 161 162 163 164 165 | return false; request = object; if (request->_method != _method || request->_protocolVersion.major != _protocolVersion.major || request->_protocolVersion.minor != _protocolVersion.minor || | | | | | | | 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 | return false; request = object; if (request->_method != _method || request->_protocolVersion.major != _protocolVersion.major || request->_protocolVersion.minor != _protocolVersion.minor || ![request->_URI isEqual: _URI] || ![request->_headers isEqual: _headers]) return false; if (request.remoteAddress != self.remoteAddress && !OFSocketAddressEqual(request.remoteAddress, self.remoteAddress)) return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddByte(&hash, _method); OFHashAddByte(&hash, _protocolVersion.major); OFHashAddByte(&hash, _protocolVersion.minor); OFHashAddHash(&hash, _URI.hash); OFHashAddHash(&hash, _headers.hash); if (_hasRemoteAddress) OFHashAddHash(&hash, OFSocketAddressHash(&_remoteAddress)); OFHashFinalize(&hash); return hash; |
︙ | ︙ | |||
252 253 254 255 256 257 258 | if (_hasRemoteAddress) remoteAddress = OFSocketAddressString(&_remoteAddress); else remoteAddress = nil; ret = [[OFString alloc] initWithFormat: | | | | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | if (_hasRemoteAddress) remoteAddress = OFSocketAddressString(&_remoteAddress); else remoteAddress = nil; ret = [[OFString alloc] initWithFormat: @"<%@:\n\tURI = %@\n" @"\tMethod = %s\n" @"\tHeaders = %@\n" @"\tRemote address = %@\n" @">", self.class, _URI, method, indentedHeaders, remoteAddress]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFHTTPResponse.h from [b3d8087036] to [3c482db81b].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 | @class OFArray OF_GENERIC(ObjectType); /** * @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h * * @brief A class for representing an HTTP request response as a stream. */ @interface OFHTTPResponse: OFStream { OFHTTPRequestProtocolVersion _protocolVersion; short _statusCode; OFDictionary OF_GENERIC(OFString *, OFString *) *_headers; | > > > < > > > > > > > > | 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 | @class OFArray OF_GENERIC(ObjectType); /** * @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h * * @brief A class for representing an HTTP request response as a stream. */ #if !defined(OF_HTTP_CLIENT_M) && !defined(OF_HTTP_SERVER_M) OF_SUBCLASSING_RESTRICTED #endif @interface OFHTTPResponse: OFStream { OFHTTPRequestProtocolVersion _protocolVersion; short _statusCode; OFDictionary OF_GENERIC(OFString *, OFString *) *_headers; } /** * @brief The protocol version of the HTTP request response. * * @throw OFUnsupportedVersionException The specified version cannot be set * because it is not supported */ @property (nonatomic) OFHTTPRequestProtocolVersion protocolVersion; /** * @brief The protocol version of the HTTP request response as a string. * * @throw OFUnsupportedVersionException The specified version cannot be set * because it is not supported * @throw OFInvalidFormatException The specified version cannot be set because * it is not in a valid format */ @property (copy, nonatomic) OFString *protocolVersionString; /** * @brief The status code of the response to the HTTP request. */ @property (nonatomic) short statusCode; |
︙ | ︙ |
Modified src/OFHTTPServer.h from [a2fd4b8141] to [ba5fc5aae1].
︙ | ︙ | |||
102 103 104 105 106 107 108 | OFArray *_threadPool; #endif } /** * @brief The host on which the HTTP server will listen. * | < | > < | > < | > | 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 | OFArray *_threadPool; #endif } /** * @brief The host on which the HTTP server will listen. * * @throw OFAlreadyConnectedException The host could not be set because * @ref start had already been called */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *host; /** * @brief The port on which the HTTP server will listen. * * @throw OFAlreadyConnectedException The port could not be set because * @ref start had already been called */ @property (nonatomic) uint16_t port; /** * @brief The delegate for the HTTP server. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFHTTPServerDelegate> delegate; #ifdef OF_HAVE_THREADS /** * @brief The number of threads the OFHTTPServer should use. * * If this is larger than 1 (the default), one thread will be used to accept * incoming connections and all others will be used to handle connections. * * For maximum CPU utilization, set this to `[OFSystemInfo numberOfCPUs] + 1`. * * @throw OFAlreadyConnectedException The number of threads could not be set * because @ref start had already been called */ @property (nonatomic) size_t numberOfThreads; #endif /** * @brief The server name the server presents to clients. * |
︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | * * @return A new HTTP server */ + (instancetype)server; /** * @brief Starts the HTTP server in the current thread's run loop. */ - (void)start; /** * @brief Stops the HTTP server, meaning it will not accept any new incoming * connections, but still handle existing connections until they are * finished or timed out. */ - (void)stop; @end OF_ASSUME_NONNULL_END | > > | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | * * @return A new HTTP server */ + (instancetype)server; /** * @brief Starts the HTTP server in the current thread's run loop. * * @throw OFAlreadyConnectedException The server had already been started */ - (void)start; /** * @brief Stops the HTTP server, meaning it will not accept any new incoming * connections, but still handle existing connections until they are * finished or timed out. */ - (void)stop; @end OF_ASSUME_NONNULL_END |
Modified src/OFHTTPServer.m from [56dd1ea76e] to [e75cf57b42].
︙ | ︙ | |||
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 | * * 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 <stdlib.h> #include <string.h> #import "OFHTTPServer.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFNumber.h" #import "OFSocket+Private.h" #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" | > > | | 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 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #define OF_HTTP_SERVER_M #include "config.h" #include <errno.h> #include <stdlib.h> #include <string.h> #import "OFHTTPServer.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFNumber.h" #import "OFSocket+Private.h" #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFURI.h" #import "OFAlreadyConnectedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" |
︙ | ︙ | |||
355 356 357 358 359 360 361 | { OFString *method; OFMutableString *path; size_t pos; @try { OFString *version = [line | | | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | { OFString *method; OFMutableString *path; size_t pos; @try { OFString *version = [line substringWithRange: OFMakeRange(line.length - 9, 9)]; OFUnichar tmp; if (![version hasPrefix: @" HTTP/1."]) return [self sendErrorAndClose: 505]; tmp = [version characterAtIndex: 8]; if (tmp < '0' || tmp > '9') |
︙ | ︙ | |||
382 383 384 385 386 387 388 | @try { _method = OFHTTPRequestMethodParseName(method); } @catch (OFInvalidArgumentException *e) { return [self sendErrorAndClose: 405]; } @try { | | | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | @try { _method = OFHTTPRequestMethodParseName(method); } @catch (OFInvalidArgumentException *e) { return [self sendErrorAndClose: 405]; } @try { OFRange range = OFMakeRange(pos + 1, line.length - pos - 10); path = [[[line substringWithRange: range] mutableCopy] autorelease]; } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; } |
︙ | ︙ | |||
508 509 510 511 512 513 514 | date, _server.name]; return false; } - (void)createResponse { void *pool = objc_autoreleasePoolPush(); | | | < | | | | | | | | 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 | date, _server.name]; return false; } - (void)createResponse { void *pool = objc_autoreleasePoolPush(); OFMutableURI *URI; OFHTTPRequest *request; OFHTTPServerResponse *response; size_t pos; [_timer invalidate]; [_timer release]; _timer = nil; if (_host == nil || _port == 0) { if (_HTTPMinorVersion > 0) { [self sendErrorAndClose: 400]; return; } [_host release]; _host = [_server.host copy]; _port = [_server port]; } URI = [OFMutableURI URIWithScheme: @"http"]; URI.host = _host; if (_port != 80) URI.port = [OFNumber numberWithUnsignedShort: _port]; @try { if ((pos = [_path rangeOfString: @"?"].location) != OFNotFound) { OFString *path, *query; path = [_path substringToIndex: pos]; query = [_path substringFromIndex: pos + 1]; URI.percentEncodedPath = path; URI.percentEncodedQuery = query; } else URI.percentEncodedPath = _path; } @catch (OFInvalidFormatException *e) { objc_autoreleasePoolPop(pool); [self sendErrorAndClose: 400]; return; } [URI makeImmutable]; request = [OFHTTPRequest requestWithURI: URI]; request.method = _method; request.protocolVersion = (OFHTTPRequestProtocolVersion){ 1, _HTTPMinorVersion }; request.headers = _headers; request.remoteAddress = _socket.remoteAddress; response = [[[OFHTTPServerResponse alloc] |
︙ | ︙ |
Renamed and modified src/OFHTTPURLHandler.h [6b4755acdc] to src/OFHTTPURIHandler.h [1fbd933246].
︙ | ︙ | |||
9 10 11 12 13 14 15 | * * 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. */ | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * * 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 "OFURIHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFHTTPURIHandler: OFURIHandler @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFHTTPURLHandler.m [c4a43aad17] to src/OFHTTPURIHandler.m [9e6fa9d3fe].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * 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" | | | | < | | 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 | * 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 "OFHTTPURIHandler.h" #import "OFHTTPClient.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" @implementation OFHTTPURIHandler - (OFStream *)openItemAtURI: (OFURI *)URI mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFHTTPClient *client = [OFHTTPClient client]; OFHTTPRequest *request = [OFHTTPRequest requestWithURI: URI]; OFHTTPResponse *response = [client performRequest: request]; [response retain]; objc_autoreleasePoolPop(pool); return [response autorelease]; |
︙ | ︙ |
Modified src/OFINICategory.h from [e194c2c9e1] to [8e0c968abf].
︙ | ︙ | |||
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 | * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the long long should be returned * @param defaultValue The value to return if the key does not exist * @return The long long for the specified key or the specified default value * if it does not exist */ - (long long)longLongForKey: (OFString *)key defaultValue: (long long)defaultValue; /** * @brief Returns the bool for the specified key or the specified default value * if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the bool should be returned * @param defaultValue The value to return if the key does not exist * @return The bool for the specified key or the specified default value if it * does not exist */ - (bool)boolForKey: (OFString *)key defaultValue: (bool)defaultValue; /** * @brief Returns the float for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the float should be returned * @param defaultValue The value to return if the key does not exist * @return The float for the specified key or the specified default value if it * does not exist */ - (float)floatForKey: (OFString *)key defaultValue: (float)defaultValue; /** * @brief Returns the double for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the double should be returned * @param defaultValue The value to return if the key does not exist * @return The double for the specified key or the specified default value if * it does not exist */ - (double)doubleForKey: (OFString *)key defaultValue: (double)defaultValue; /** * @brief Returns an array of strings for the specified multi-key, or an empty * array if the key does not exist. * | > > > > > > > > | 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 | * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the long long should be returned * @param defaultValue The value to return if the key does not exist * @return The long long for the specified key or the specified default value * if it does not exist * @throw OFInvalidFormatException The specified key is not in the correct * format for a long long */ - (long long)longLongForKey: (OFString *)key defaultValue: (long long)defaultValue; /** * @brief Returns the bool for the specified key or the specified default value * if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the bool should be returned * @param defaultValue The value to return if the key does not exist * @return The bool for the specified key or the specified default value if it * does not exist * @throw OFInvalidFormatException The specified key is not in the correct * format for a bool */ - (bool)boolForKey: (OFString *)key defaultValue: (bool)defaultValue; /** * @brief Returns the float for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the float should be returned * @param defaultValue The value to return if the key does not exist * @return The float for the specified key or the specified default value if it * does not exist * @throw OFInvalidFormatException The specified key is not in the correct * format for a float */ - (float)floatForKey: (OFString *)key defaultValue: (float)defaultValue; /** * @brief Returns the double for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the double should be returned * @param defaultValue The value to return if the key does not exist * @return The double for the specified key or the specified default value if * it does not exist * @throw OFInvalidFormatException The specified key is not in the correct * format for a double */ - (double)doubleForKey: (OFString *)key defaultValue: (double)defaultValue; /** * @brief Returns an array of strings for the specified multi-key, or an empty * array if the key does not exist. * |
︙ | ︙ |
Modified src/OFINICategory.m from [0938799665] to [1db2d24df3].
︙ | ︙ | |||
54 55 56 57 58 59 60 | [mutableString replaceOccurrencesOfString: @"\\" withString: @"\\\\"]; [mutableString replaceOccurrencesOfString: @"\f" withString: @"\\f"]; [mutableString replaceOccurrencesOfString: @"\r" withString: @"\\r"]; [mutableString replaceOccurrencesOfString: @"\n" withString: @"\\n"]; [mutableString replaceOccurrencesOfString: @"\"" withString: @"\\\""]; | | | | 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 | [mutableString replaceOccurrencesOfString: @"\\" withString: @"\\\\"]; [mutableString replaceOccurrencesOfString: @"\f" withString: @"\\f"]; [mutableString replaceOccurrencesOfString: @"\r" withString: @"\\r"]; [mutableString replaceOccurrencesOfString: @"\n" withString: @"\\n"]; [mutableString replaceOccurrencesOfString: @"\"" withString: @"\\\""]; [mutableString insertString: @"\"" atIndex: 0]; [mutableString appendString: @"\""]; [mutableString makeImmutable]; return mutableString; } static OFString * unescapeString(OFString *string) { OFMutableString *mutableString; if (![string hasPrefix: @"\""] || ![string hasSuffix: @"\""]) return string; string = [string substringWithRange: OFMakeRange(1, string.length - 2)]; mutableString = [[string mutableCopy] autorelease]; [mutableString replaceOccurrencesOfString: @"\\f" withString: @"\f"]; [mutableString replaceOccurrencesOfString: @"\\r" withString: @"\r"]; [mutableString replaceOccurrencesOfString: @"\\n" withString: @"\n"]; [mutableString replaceOccurrencesOfString: @"\\\"" withString: @"\""]; [mutableString replaceOccurrencesOfString: @"\\\\" withString: @"\\"]; |
︙ | ︙ |
Modified src/OFINIFile.h from [de47c3e875] to [f35fd21473].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #import "OFObject.h" #import "OFString.h" #import "OFINICategory.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableArray OF_GENERIC(ObjectType); | | | > > > > | | < > > > > | | > > > > | | < > > > > | | | | | | 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 | #import "OFObject.h" #import "OFString.h" #import "OFINICategory.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableArray OF_GENERIC(ObjectType); @class OFURI; /** * @class OFINIFile OFINIFile.h ObjFW/OFINIFile.h * * @brief A class for reading, creating and modifying INI files. */ OF_SUBCLASSING_RESTRICTED @interface OFINIFile: OFObject { OFMutableArray OF_GENERIC(OFINICategory *) *_categories; } /** * @brief All categories in the INI file. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFINICategory *) *categories; /** * @brief Creates a new OFINIFile with the contents of the specified file. * * @param URI The URI to the file whose contents the OFINIFile should contain * * @return A new, autoreleased OFINIFile with the contents of the specified file * @throw OFInvalidFormatException The format of the specified INI file is * invalid * @throw OFInvalidEncodingException The INI file is not in the specified * encoding */ + (instancetype)fileWithURI: (OFURI *)URI; /** * @brief Creates a new OFINIFile with the contents of the specified file in * the specified encoding. * * @param URI The URI to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file * @return A new, autoreleased OFINIFile with the contents of the specified file * @throw OFInvalidFormatException The format of the specified INI file is * invalid * @throw OFInvalidEncodingException The INI file is not in the specified * encoding */ + (instancetype)fileWithURI: (OFURI *)URI encoding: (OFStringEncoding)encoding; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFINIFile with the contents of the * specified file. * * @param URI The URI to the file whose contents the OFINIFile should contain * * @return An initialized OFINIFile with the contents of the specified file * @throw OFInvalidFormatException The format of the specified INI file is * invalid * @throw OFInvalidEncodingException The INI file is not in the specified * encoding */ - (instancetype)initWithURI: (OFURI *)URI; /** * @brief Initializes an already allocated OFINIFile with the contents of the * specified file in the specified encoding. * * @param URI The URI to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file * @return An initialized OFINIFile with the contents of the specified file * @throw OFInvalidFormatException The format of the specified INI file is * invalid * @throw OFInvalidEncodingException The INI file is not in the specified * encoding */ - (instancetype)initWithURI: (OFURI *)URI encoding: (OFStringEncoding)encoding OF_DESIGNATED_INITIALIZER; /** * @brief Returns an @ref OFINICategory for the category with the specified * name. * * @param name The name of the category for which an @ref OFINICategory should * be returned * * @return An @ref OFINICategory for the category with the specified name */ - (OFINICategory *)categoryForName: (OFString *)name; /** * @brief Writes the contents of the OFINIFile to a file. * * @param URI The URI of the file to write to */ - (void)writeToURI: (OFURI *)URI; /** * @brief Writes the contents of the OFINIFile to a file in the specified * encoding. * * @param URI The URI of the file to write to * @param encoding The encoding to use */ - (void)writeToURI: (OFURI *)URI encoding: (OFStringEncoding)encoding; @end OF_ASSUME_NONNULL_END |
Modified src/OFINIFile.m from [5568ad8169] to [7850530cf1].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFINIFile.h" #import "OFArray.h" #import "OFINICategory+Private.h" #import "OFINICategory.h" #import "OFStream.h" #import "OFString.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 | #import "OFINIFile.h" #import "OFArray.h" #import "OFINICategory+Private.h" #import "OFINICategory.h" #import "OFStream.h" #import "OFString.h" #import "OFURI.h" #import "OFURIHandler.h" #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" OF_DIRECT_MEMBERS @interface OFINIFile () - (void)of_parseURI: (OFURI *)URI encoding: (OFStringEncoding)encoding; @end static bool isWhitespaceLine(OFString *line) { const char *cString = line.UTF8String; size_t length = line.UTF8StringLength; for (size_t i = 0; i < length; i++) if (!OFASCIIIsSpace(cString[i])) return false; return true; } @implementation OFINIFile @synthesize categories = _categories; + (instancetype)fileWithURI: (OFURI *)URI { return [[[self alloc] initWithURI: URI] autorelease]; } + (instancetype)fileWithURI: (OFURI *)URI encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithURI: URI encoding: encoding] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithURI: (OFURI *)URI { return [self initWithURI: URI encoding: OFStringEncodingAutodetect]; } - (instancetype)initWithURI: (OFURI *)URI encoding: (OFStringEncoding)encoding { self = [super init]; @try { _categories = [[OFMutableArray alloc] init]; [self of_parseURI: URI encoding: encoding]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
106 107 108 109 110 111 112 | [_categories addObject: category]; objc_autoreleasePoolPop(pool); return category; } | | > > > < | | | | | | < < | 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 | [_categories addObject: category]; objc_autoreleasePoolPop(pool); return category; } - (void)of_parseURI: (OFURI *)URI encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFStream *file; OFINICategory *category = nil; OFString *line; if (encoding == OFStringEncodingAutodetect) encoding = OFStringEncodingUTF8; @try { file = [OFURIHandler openItemAtURI: URI mode: @"r"]; } @catch (OFOpenItemFailedException *e) { /* Handle missing file like an empty file */ if (e.errNo == ENOENT) return; @throw e; } while ((line = [file readLineWithEncoding: encoding]) != nil) { if (isWhitespaceLine(line)) continue; if ([line hasPrefix: @"["]) { OFString *categoryName; if (![line hasSuffix: @"]"]) @throw [OFInvalidFormatException exception]; categoryName = [line substringWithRange: OFMakeRange(1, line.length - 2)]; category = [[[OFINICategory alloc] of_initWithName: categoryName] autorelease]; [_categories addObject: category]; } else { if (category == nil) @throw [OFInvalidFormatException exception]; [category of_parseLine: line]; } } objc_autoreleasePoolPop(pool); } - (void)writeToURI: (OFURI *)URI { [self writeToURI: URI encoding: OFStringEncodingUTF8]; } - (void)writeToURI: (OFURI *)URI encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFStream *file = [OFURIHandler openItemAtURI: URI mode: @"w"]; bool first = true; for (OFINICategory *category in _categories) if ([category of_writeToStream: file encoding: encoding first: first]) first = false; |
︙ | ︙ |
Modified src/OFINIFileSettings.h from [e6622a40c7] to [125e92a3e8].
︙ | ︙ | |||
15 16 17 18 19 20 21 | #import "OFSettings.h" OF_ASSUME_NONNULL_BEGIN @class OFINIFile; @class OFString; | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #import "OFSettings.h" OF_ASSUME_NONNULL_BEGIN @class OFINIFile; @class OFString; @class OFURI; @interface OFINIFileSettings: OFSettings { OFURI *_fileURI; OFINIFile *_INIFile; } @end OF_ASSUME_NONNULL_END |
Modified src/OFINIFileSettings.m from [06a12ac82c] to [b3d1a39e2b].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #include "config.h" #import "OFINIFileSettings.h" #import "OFArray.h" #import "OFINIFile.h" #import "OFString.h" #import "OFSystemInfo.h" | | | | | | | 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 | #include "config.h" #import "OFINIFileSettings.h" #import "OFArray.h" #import "OFINIFile.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFURI.h" @implementation OFINIFileSettings - (instancetype)initWithApplicationName: (OFString *)applicationName { self = [super initWithApplicationName: applicationName]; @try { void *pool = objc_autoreleasePoolPush(); OFString *fileName; fileName = [applicationName stringByAppendingString: @".ini"]; _fileURI = [[[OFSystemInfo userConfigURI] URIByAppendingPathComponent: fileName] copy]; _INIFile = [[OFINIFile alloc] initWithURI: _fileURI]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_fileURI release]; [_INIFile release]; [super dealloc]; } - (void)of_getCategory: (OFString **)category andKey: (OFString **)key |
︙ | ︙ | |||
239 240 241 242 243 244 245 | [[_INIFile categoryForName: category] removeValueForKey: key]; objc_autoreleasePoolPop(pool); } - (void)save { | | | 239 240 241 242 243 244 245 246 247 248 | [[_INIFile categoryForName: category] removeValueForKey: key]; objc_autoreleasePoolPop(pool); } - (void)save { [_INIFile writeToURI: _fileURI]; } @end |
Modified src/OFIPXSocket.h from [a2ca3d4d82] to [8dc615311a].
︙ | ︙ | |||
32 33 34 35 36 37 38 | * * @brief A class which provides methods to create and use IPX sockets. * * Addresses are of type @ref OFSocketAddress. You can use * @ref OFSocketAddressMakeIPX to create an address or * @ref OFSocketAddressIPXNetwork to get the IPX network, * @ref OFSocketAddressIPXNode to get the IPX node and | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * * @brief A class which provides methods to create and use IPX sockets. * * Addresses are of type @ref OFSocketAddress. You can use * @ref OFSocketAddressMakeIPX to create an address or * @ref OFSocketAddressIPXNetwork to get the IPX network, * @ref OFSocketAddressIPXNode to get the IPX node and * @ref OFSocketAddressIPXPort 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 |
︙ | ︙ | |||
63 64 65 66 67 68 69 70 | @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 | > > > | > > | > > > > | 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 | @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 network The IPX network to bind to. 0 means the current network. * @param node The IPX network to bind to. An all zero node means the * computer's node. * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return via the returned socket address. * @param packetType The packet type to use on the socket * @return The address on which this socket can be reached * @throw OFBindIPXSocketFailedException Binding failed * @throw OFAlreadyConnectedException The socket is already bound */ - (OFSocketAddress) bindToNetwork: (uint32_t)network node: (const unsigned char [_Nonnull IPX_NODE_LEN])node port: (uint16_t)port packetType: (uint8_t)packetType; @end OF_ASSUME_NONNULL_END |
Modified src/OFIPXSocket.m from [f0059481b5] to [1dc137a6b3].
︙ | ︙ | |||
22 23 24 25 26 27 28 | #endif #import "OFIPXSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAlreadyConnectedException.h" | | > > > | < | | | > > | | | > | > > | | | > | > > | | | > | > > | | | | 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 | #endif #import "OFIPXSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindIPXSocketFailedException.h" @implementation OFIPXSocket @dynamic delegate; - (OFSocketAddress)bindToNetwork: (uint32_t)network node: (const unsigned char [IPX_NODE_LEN])node port: (uint16_t)port packetType: (uint8_t)packetType { OFSocketAddress address; int protocol = 0; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeIPX(network, node, port); #ifdef OF_WINDOWS protocol = NSPROTO_IPX + packetType; #else _packetType = address.sockaddr.ipx.sipx_type = packetType; #endif if ((_socket = socket(address.sockaddr.ipx.sipx_family, SOCK_DGRAM | SOCK_CLOEXEC, protocol)) == OFInvalidSocketHandle) @throw [OFBindIPXSocketFailedException exceptionWithNetwork: network node: node port: port packetType: packetType socket: self errNo: OFSocketErrNo()]; _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, (struct sockaddr *)&address.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindIPXSocketFailedException exceptionWithNetwork: network node: node port: port packetType: packetType socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPX; address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, (struct sockaddr *)&address.sockaddr, &address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindIPXSocketFailedException exceptionWithNetwork: network node: node port: port packetType: packetType socket: self errNo: errNo]; } if (address.sockaddr.ipx.sipx_family != AF_IPX) { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindIPXSocketFailedException exceptionWithNetwork: network node: node port: port packetType: packetType socket: self errNo: EAFNOSUPPORT]; } return address; } #ifndef OF_WINDOWS - (void)sendBuffer: (const void *)buffer |
︙ | ︙ |
Modified src/OFInvocation.h from [324ba0dca4] to [ab7d9433d5].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 | @class OFMutableData; /** * @class OFInvocation OFInvocation.h ObjFW/OFInvocation.h * * @brief A class for storing and accessing invocations, and invoking them. */ @interface OFInvocation: OFObject { OFMethodSignature *_methodSignature; OFMutableArray OF_GENERIC(OFMutableData *) *_arguments; OFMutableData *_returnValue; | > < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | @class OFMutableData; /** * @class OFInvocation OFInvocation.h ObjFW/OFInvocation.h * * @brief A class for storing and accessing invocations, and invoking them. */ OF_SUBCLASSING_RESTRICTED @interface OFInvocation: OFObject { OFMethodSignature *_methodSignature; OFMutableArray OF_GENERIC(OFMutableData *) *_arguments; OFMutableData *_returnValue; } /** * @brief The method signature for the invocation. */ @property (readonly, nonatomic) OFMethodSignature *methodSignature; |
︙ | ︙ |
Modified src/OFKernelEventObserver.h from [21aebcf8a0] to [81efdafa0c].
︙ | ︙ | |||
41 42 43 44 45 46 47 | */ @protocol OFKernelEventObserverDelegate <OFObject> @optional /** * @brief This callback is called when an object did get ready for reading. * * @note If the object is a subclass of @ref OFStream and | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | */ @protocol OFKernelEventObserverDelegate <OFObject> @optional /** * @brief This callback is called when an object did get ready for reading. * * @note If the object is a subclass of @ref OFStream and * @ref OFStream::tryReadLine or @ref OFStream::tryReadUntilDelimiter: * has been called on the stream, this callback will not be called again * until new data has been received, even though there is still data in * the cache. The reason for this is to prevent spinning in a loop when * there is an incomplete string in the cache. Once the string has been * completed, the callback will be called again as long there is data in * the cache. * * @param object The object which did become ready for reading |
︙ | ︙ | |||
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 | * This is also used to observe a listening socket for incoming connections, * which then triggers a read event for the observed object. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent blocking even though the newly added object is ready. * * @param object The object to observe for reading */ - (void)addObjectForReading: (id <OFReadyForReadingObserving>)object; /** * @brief Adds an object to observe for writing. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent blocking even though the newly added object is ready. * * @param object The object to observe for writing */ - (void)addObjectForWriting: (id <OFReadyForWritingObserving>)object; /** * @brief Removes an object to observe for reading. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent the removed object from still being observed. * * @param object The object to remove from observing for reading */ - (void)removeObjectForReading: (id <OFReadyForReadingObserving>)object; /** * @brief Removes an object to observe for writing. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent the removed object from still being observed. * * @param object The object to remove from observing for writing */ - (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object; /** * @brief Observes all objects and blocks until an event happens on an object. */ - (void)observe; /** * @brief Observes all objects until an event happens on an object or the * timeout is reached. * * @param timeInterval The time to wait for an event, in seconds */ - (void)observeForTimeInterval: (OFTimeInterval)timeInterval; /** * @brief Observes all objects until an event happens on an object or the * specified date is reached. * * @param date The until which to observe */ - (void)observeUntilDate: (OFDate *)date; /** * @brief Cancels the currently blocking observe call. * * This is the only method that can and should be called from another thread | > > > > > > > > > > > > > > > | 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 | * This is also used to observe a listening socket for incoming connections, * which then triggers a read event for the observed object. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent blocking even though the newly added object is ready. * * @param object The object to observe for reading * @throw OFObserveKernelEventsFailedException Adding the object for observing * failed */ - (void)addObjectForReading: (id <OFReadyForReadingObserving>)object; /** * @brief Adds an object to observe for writing. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent blocking even though the newly added object is ready. * * @param object The object to observe for writing * @throw OFObserveKernelEventsFailedException Adding the object for observing * failed */ - (void)addObjectForWriting: (id <OFReadyForWritingObserving>)object; /** * @brief Removes an object to observe for reading. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent the removed object from still being observed. * * @param object The object to remove from observing for reading * @throw OFObserveKernelEventsFailedException Removing the object for observing * failed */ - (void)removeObjectForReading: (id <OFReadyForReadingObserving>)object; /** * @brief Removes an object to observe for writing. * * If there is an @ref observe call blocking, it will be canceled. The reason * for this is to prevent the removed object from still being observed. * * @param object The object to remove from observing for writing * @throw OFObserveKernelEventsFailedException Removing the object for observing * failed */ - (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object; /** * @brief Observes all objects and blocks until an event happens on an object. * * @throw OFObserveKernelEventsFailedException Observing for kernel events * failed */ - (void)observe; /** * @brief Observes all objects until an event happens on an object or the * timeout is reached. * * @param timeInterval The time to wait for an event, in seconds * @throw OFObserveKernelEventsFailedException Observing for kernel events * failed */ - (void)observeForTimeInterval: (OFTimeInterval)timeInterval; /** * @brief Observes all objects until an event happens on an object or the * specified date is reached. * * @param date The until which to observe * @throw OFObserveKernelEventsFailedException Observing for kernel events * failed */ - (void)observeUntilDate: (OFDate *)date; /** * @brief Cancels the currently blocking observe call. * * This is the only method that can and should be called from another thread |
︙ | ︙ |
Modified src/OFKeyValueCoding.h from [06cc2c1de6] to [3568d90874].
︙ | ︙ | |||
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 | */ @protocol OFKeyValueCoding /** * @brief Returns the value for the specified key. * * @param key The key of the value to return * @return The value for the specified key */ - (nullable id)valueForKey: (OFString *)key; /** * @brief Returns the value for the specified key path. * * @param keyPath The key path of the value to return * @return The value for the specified key path */ - (nullable id)valueForKeyPath: (OFString *)keyPath; /** * @brief This is called by @ref valueForKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * * @param key The undefined key of the value to return * @return The value for the specified undefined key */ - (nullable id)valueForUndefinedKey: (OFString *)key; /** * @brief Set the value for the specified key. * * @param value The value for the specified key * @param key The key of the value to set */ - (void)setValue: (nullable id)value forKey: (OFString *)key; /** * @brief Set the value for the specified key path. * * @param value The value for the specified key path * @param keyPath The key path of the value to set */ - (void)setValue: (nullable id)value forKeyPath: (OFString *)keyPath; /** * @brief This is called by @ref setValue:forKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * * @param value The value for the specified undefined key * @param key The undefined key of the value to set */ - (void)setValue: (nullable id)value forUndefinedKey: (OFString *)key; /** * @brief This is called by @ref setValue:forKey: if the specified key is a * scalar, but the value specified is `nil`. * | > > > > > > > > > > > > | 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 | */ @protocol OFKeyValueCoding /** * @brief Returns the value for the specified key. * * @param key The key of the value to return * @return The value for the specified key * @throw OFUndefinedKeyException The specified key does not exist and * @ref valueForUndefinedKey: was not overridden */ - (nullable id)valueForKey: (OFString *)key; /** * @brief Returns the value for the specified key path. * * @param keyPath The key path of the value to return * @return The value for the specified key path * @throw OFUndefinedKeyException The specified key does not exist and * @ref valueForUndefinedKey: was not overridden */ - (nullable id)valueForKeyPath: (OFString *)keyPath; /** * @brief This is called by @ref valueForKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * * @param key The undefined key of the value to return * @return The value for the specified undefined key * @throw OFUndefinedKeyException The specified key does not exist */ - (nullable id)valueForUndefinedKey: (OFString *)key; /** * @brief Set the value for the specified key. * * @param value The value for the specified key * @param key The key of the value to set * @throw OFUndefinedKeyException The specified key does not exist and * @ref setValue:forUndefinedKey: was not * overridden */ - (void)setValue: (nullable id)value forKey: (OFString *)key; /** * @brief Set the value for the specified key path. * * @param value The value for the specified key path * @param keyPath The key path of the value to set * @throw OFUndefinedKeyException The specified key does not exist and * @ref setValue:forUndefinedKey: was not * overridden */ - (void)setValue: (nullable id)value forKeyPath: (OFString *)keyPath; /** * @brief This is called by @ref setValue:forKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * * @param value The value for the specified undefined key * @param key The undefined key of the value to set * @throw OFUndefinedKeyException The specified key does not exist */ - (void)setValue: (nullable id)value forUndefinedKey: (OFString *)key; /** * @brief This is called by @ref setValue:forKey: if the specified key is a * scalar, but the value specified is `nil`. * |
︙ | ︙ |
Modified src/OFKqueueKernelEventObserver.m from [bcb05813e9] to [ef6117c8da].
︙ | ︙ | |||
27 28 29 30 31 32 33 | #include <sys/event.h> #include <sys/time.h> #import "OFKqueueKernelEventObserver.h" #import "OFArray.h" #import "OFInitializationFailedException.h" | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <sys/event.h> #include <sys/time.h> #import "OFKqueueKernelEventObserver.h" #import "OFArray.h" #import "OFInitializationFailedException.h" #import "OFObserveKernelEventsFailedException.h" #import "OFOutOfRangeException.h" #define eventListSize 64 @implementation OFKqueueKernelEventObserver - (instancetype)init { |
︙ | ︙ | |||
90 91 92 93 94 95 96 | /* * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but * switched this to `void *` in NetBSD 10. */ event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) | > | | > | | > | | > | | > | | | | 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 | /* * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but * switched this to `void *` in NetBSD 10. */ event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [super addObjectForReading: object]; } - (void)addObjectForWriting: (id <OFReadyForWritingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForWriting; event.filter = EVFILT_WRITE; event.flags = EV_ADD; /* * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but * switched this to `void *` in NetBSD 10. */ event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [super addObjectForWriting: object]; } - (void)removeObjectForReading: (id <OFReadyForReadingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForReading; event.filter = EVFILT_READ; event.flags = EV_DELETE; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [super removeObjectForReading: object]; } - (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForWriting; event.filter = EVFILT_WRITE; event.flags = EV_DELETE; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; [super removeObjectForWriting: object]; } - (void)observeForTimeInterval: (OFTimeInterval)timeInterval { struct timespec timeout; struct kevent eventList[eventListSize]; int events; if ([self of_processReadBuffers]) return; timeout.tv_sec = (time_t)timeInterval; timeout.tv_nsec = (long)((timeInterval - timeout.tv_sec) * 1000000000); events = kevent(_kernelQueue, NULL, 0, eventList, eventListSize, (timeInterval != -1 ? &timeout : NULL)); if (events < 0) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: errno]; for (int i = 0; i < events; i++) { void *pool; if (eventList[i].flags & EV_ERROR) @throw [OFObserveKernelEventsFailedException exceptionWithObserver: self errNo: (int)eventList[i].data]; if (eventList[i].ident == (uintptr_t)_cancelFD[0]) { char buffer; assert(eventList[i].filter == EVFILT_READ); |
︙ | ︙ |
Modified src/OFLHAArchive.h from [eaf15d177e] to [038ec719a6].
︙ | ︙ | |||
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 | #import "OFKernelEventObserver.h" #import "OFLHAArchiveEntry.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN @class OFStream; /** * @class OFLHAArchive OFLHAArchive.h ObjFW/OFLHAArchive.h * * @brief A class for accessing and manipulating LHA files. */ OF_SUBCLASSING_RESTRICTED @interface OFLHAArchive: OFObject { OFStream *_stream; uint_least8_t _mode; OFStringEncoding _encoding; OFStream *_Nullable _lastReturnedStream; } /** * @brief The encoding to use for the archive. Defaults to ISO 8859-1. */ @property (nonatomic) OFStringEncoding encoding; | > > > > > < < < < < < < < < < < | | | > > > > > > > > > > < | | < > > > > > > > > > > > > > > > > | 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 | #import "OFKernelEventObserver.h" #import "OFLHAArchiveEntry.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN @class OFStream; @class OFURI; /** * @class OFLHAArchive OFLHAArchive.h ObjFW/OFLHAArchive.h * * @brief A class for accessing and manipulating LHA files. */ OF_SUBCLASSING_RESTRICTED @interface OFLHAArchive: OFObject { OFStream *_stream; uint_least8_t _mode; OFStringEncoding _encoding; OFLHAArchiveEntry *_Nullable _currentEntry; #ifdef OF_LHA_ARCHIVE_M @public #endif OFStream *_Nullable _lastReturnedStream; } /** * @brief The encoding to use for the archive. Defaults to ISO 8859-1. */ @property (nonatomic) OFStringEncoding encoding; /** * @brief Creates a new OFLHAArchive object with the specified stream. * * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; /** * @brief Creates a new OFLHAArchive object with the specified file. * * @param URI The URI to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ + (instancetype)archiveWithURI: (OFURI *)URI mode: (OFString *)mode; /** * @brief Creates a URI for accessing a the specified file within the specified * LHA archive. * * @param path The path of the file within the archive * @param URI The URI of the archive * @return A URI for accessing the specified file within the specified LHA * archive */ + (OFURI *)URIForFilePath: (OFString *)path inArchiveWithURI: (OFURI *)URI; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFLHAArchive object with the * specified stream. * * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFLHAArchive */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; /** * @brief Initializes an already allocated OFLHAArchive object with the * specified file. * * @param URI The URI to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFLHAArchive */ - (instancetype)initWithURI: (OFURI *)URI mode: (OFString *)mode; /** * @brief Returns the next entry from the LHA archive or `nil` if all entries * have been read. * * @note This is only available in read mode. * * @warning Calling @ref nextEntry will invalidate all streams returned by * @ref streamForReadingCurrentEntry or * @ref streamForWritingEntry:! Reading from or writing to an * invalidated stream will throw an @ref OFReadFailedException or * @ref OFWriteFailedException! * * @return The next entry from the LHA archive or `nil` if all entries have * been read * @throw OFInvalidFormatException The archive's format is invalid * @throw OFUnsupportedVersionException The archive's format is of an * unsupported version * @throw OFTruncatedDataException The archive was truncated */ - (nullable OFLHAArchiveEntry *)nextEntry; /** * @brief Returns a stream for reading the current entry. * * @note This is only available in read mode. * * @note The returned stream conforms to @ref OFReadyForReadingObserving if the * underlying stream does so, too. * * @return A stream for reading the current entry */ - (OFStream *)streamForReadingCurrentEntry; /** * @brief Returns a stream for writing the specified entry. * * @note This is only available in write and append mode. * * @note The uncompressed size, compressed size and CRC16 of the specified * entry are ignored. |
︙ | ︙ | |||
143 144 145 146 147 148 149 150 151 152 153 154 | * @param entry The entry for which a stream for writing should be returned * @return A stream for writing the specified entry */ - (OFStream *)streamForWritingEntry: (OFLHAArchiveEntry *)entry; /** * @brief Closes the OFLHAArchive. */ - (void)close; @end OF_ASSUME_NONNULL_END | > > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | * @param entry The entry for which a stream for writing should be returned * @return A stream for writing the specified entry */ - (OFStream *)streamForWritingEntry: (OFLHAArchiveEntry *)entry; /** * @brief Closes the OFLHAArchive. * * @throw OFNotOpenException The archive is not open */ - (void)close; @end OF_ASSUME_NONNULL_END |
Modified src/OFLHAArchive.m from [5dc375ab00] to [fa04eb799a].
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | * * 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 "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" | > > | < | < > | | > > | | > | > | > | | | < | | | > > > > | 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 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #define OF_LHA_ARCHIVE_M #include "config.h" #include <errno.h> #import "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" #import "OFArchiveURIHandler.h" #import "OFCRC16.h" #import "OFLHADecompressingStream.h" #import "OFSeekableStream.h" #import "OFStream.h" #import "OFString.h" #import "OFURI.h" #import "OFURIHandler.h" #import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" enum { modeRead, modeWrite, modeAppend }; OF_DIRECT_MEMBERS @interface OFLHAArchiveFileReadStream: OFStream <OFReadyForReadingObserving> { OFLHAArchive *_archive; OFStream *_stream, *_decompressedStream; OFLHAArchiveEntry *_entry; unsigned long long _toRead; uint16_t _CRC16; bool _atEndOfStream, _skipped; } - (instancetype)of_initWithArchive: (OFLHAArchive *)archive stream: (OFStream *)stream entry: (OFLHAArchiveEntry *)entry; - (void)of_skip; @end OF_DIRECT_MEMBERS @interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving> { OFLHAArchive *_archive; OFMutableLHAArchiveEntry *_entry; OFStringEncoding _encoding; OFSeekableStream *_stream; OFStreamOffset _headerOffset; uint32_t _bytesWritten; uint16_t _CRC16; } - (instancetype)of_initWithArchive: (OFLHAArchive *)archive stream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (OFStringEncoding)encoding; @end @implementation OFLHAArchive @synthesize encoding = _encoding; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } + (instancetype)archiveWithURI: (OFURI *)URI mode: (OFString *)mode { return [[[self alloc] initWithURI: URI mode: mode] autorelease]; } + (OFURI *)URIForFilePath: (OFString *)path inArchiveWithURI: (OFURI *)URI { return OFArchiveURIHandlerURIForFileInArchive(@"lha", path, URI); } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode |
︙ | ︙ | |||
112 113 114 115 116 117 118 | if ((_mode == modeWrite || _mode == modeAppend) && ![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; if (_mode == modeAppend) [(OFSeekableStream *)_stream seekToOffset: 0 | | < | > | > | | | < > > > > | | | < < | > < > > < > > > < | | < < < < | | | > > | > > > > | 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 | if ((_mode == modeWrite || _mode == modeAppend) && ![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; if (_mode == modeAppend) [(OFSeekableStream *)_stream seekToOffset: 0 whence: OFSeekEnd]; _encoding = OFStringEncodingISO8859_1; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithURI: (OFURI *)URI mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFStream *stream; @try { if ([mode isEqual: @"a"]) stream = [OFURIHandler openItemAtURI: URI mode: @"r+"]; else stream = [OFURIHandler openItemAtURI: URI mode: mode]; } @catch (id e) { [self release]; @throw e; } self = [self initWithStream: stream mode: mode]; objc_autoreleasePoolPop(pool); return self; } - (void)dealloc { if (_stream != nil) [self close]; [_currentEntry release]; [super dealloc]; } - (OFLHAArchiveEntry *)nextEntry { char header[21]; size_t headerLen; if (_mode != modeRead) @throw [OFInvalidArgumentException exception]; [_currentEntry release]; _currentEntry = nil; [(OFLHAArchiveFileReadStream *)_lastReturnedStream of_skip]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } _lastReturnedStream = nil; for (headerLen = 0; headerLen < 21;) { if (_stream.atEndOfStream) { if (headerLen == 0) return nil; if (headerLen == 1 && header[0] == 0) return nil; @throw [OFTruncatedDataException exception]; } headerLen += [_stream readIntoBuffer: header + headerLen length: 21 - headerLen]; } _currentEntry= [[OFLHAArchiveEntry alloc] of_initWithHeader: header stream: _stream encoding: _encoding]; return _currentEntry; } - (OFStream *)streamForReadingCurrentEntry { if (_mode != modeRead) @throw [OFInvalidArgumentException exception]; if (_currentEntry == nil) @throw [OFInvalidArgumentException exception]; _lastReturnedStream = [[[OFLHAArchiveFileReadStream alloc] of_initWithArchive: self stream: _stream entry: _currentEntry] autorelease]; [_currentEntry release]; _currentEntry = nil; return _lastReturnedStream; } - (OFStream *)streamForWritingEntry: (OFLHAArchiveEntry *)entry { OFString *compressionMethod; if (_mode != modeWrite && _mode != modeAppend) |
︙ | ︙ | |||
227 228 229 230 231 232 233 | object: self]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } | < | > | | | | < < | > | > | 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 | object: self]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } _lastReturnedStream = nil; _lastReturnedStream = [[[OFLHAArchiveFileWriteStream alloc] of_initWithArchive: self stream: (OFSeekableStream *)_stream entry: entry encoding: _encoding] autorelease]; return _lastReturnedStream; } - (void)close { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } _lastReturnedStream = nil; [_stream release]; _stream = nil; } @end @implementation OFLHAArchiveFileReadStream - (instancetype)of_initWithArchive: (OFLHAArchive *)archive stream: (OFStream *)stream entry: (OFLHAArchiveEntry *)entry { self = [super init]; @try { OFString *compressionMethod; _archive = [archive retain]; _stream = [stream retain]; compressionMethod = entry.compressionMethod; if ([compressionMethod isEqual: @"-lh4-"] || [compressionMethod isEqual: @"-lh5-"]) _decompressedStream = [[OFLHADecompressingStream alloc] |
︙ | ︙ | |||
306 307 308 309 310 311 312 313 314 315 316 317 318 319 | - (void)dealloc { if (_stream != nil || _decompressedStream != nil) [self close]; [_entry release]; [super dealloc]; } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; | > > > > > | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | - (void)dealloc { if (_stream != nil || _decompressedStream != nil) [self close]; [_entry release]; if (_archive->_lastReturnedStream == self) _archive->_lastReturnedStream = nil; [_archive release]; [super dealloc]; } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; |
︙ | ︙ | |||
331 332 333 334 335 336 337 | if (_atEndOfStream) return 0; if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer) @throw [OFTruncatedDataException exception]; if (length > _toRead) | | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | if (_atEndOfStream) return 0; if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer) @throw [OFTruncatedDataException exception]; if (length > _toRead) length = (size_t)_toRead; ret = [_decompressedStream readIntoBuffer: buffer length: length]; _toRead -= ret; _CRC16 = OFCRC16(_CRC16, buffer, ret); if (_toRead == 0) { |
︙ | ︙ | |||
371 372 373 374 375 376 377 | return ((id <OFReadyForReadingObserving>)_decompressedStream) .fileDescriptorForReading; } - (void)of_skip { OFStream *stream; | | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | return ((id <OFReadyForReadingObserving>)_decompressedStream) .fileDescriptorForReading; } - (void)of_skip { OFStream *stream; unsigned long long toRead; if (_stream == nil || _skipped) return; stream = _stream; toRead = _toRead; |
︙ | ︙ | |||
396 397 398 399 400 401 402 | toRead = _entry.compressedSize - decompressingStream.bytesConsumed; stream = _stream; } if ([stream isKindOfClass: [OFSeekableStream class]] && | | | | | | > | 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 | toRead = _entry.compressedSize - decompressingStream.bytesConsumed; stream = _stream; } if ([stream isKindOfClass: [OFSeekableStream class]] && toRead < LLONG_MAX && (long long)toRead == (OFStreamOffset)toRead) [(OFSeekableStream *)stream seekToOffset: (OFStreamOffset)toRead whence: OFSeekCurrent]; else { while (toRead > 0) { char buffer[512]; unsigned long long min = toRead; if (min > 512) min = 512; toRead -= [stream readIntoBuffer: buffer length: (size_t)min]; } } _toRead = 0; _skipped = true; } |
︙ | ︙ | |||
433 434 435 436 437 438 439 | _decompressedStream = nil; [super close]; } @end @implementation OFLHAArchiveFileWriteStream | > | | | > | | 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 | _decompressedStream = nil; [super close]; } @end @implementation OFLHAArchiveFileWriteStream - (instancetype)of_initWithArchive: (OFLHAArchive *)archive stream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (OFStringEncoding)encoding { self = [super init]; @try { _archive = [archive retain]; _entry = [entry mutableCopy]; _encoding = encoding; _headerOffset = [stream seekToOffset: 0 whence: OFSeekCurrent]; [_entry of_writeToStream: stream encoding: _encoding]; /* * Retain stream last, so that -[close] called by -[dealloc] * doesn't write in case of an error. */ _stream = [stream retain]; |
︙ | ︙ | |||
465 466 467 468 469 470 471 472 473 474 475 476 477 478 | - (void)dealloc { if (_stream != nil) [self close]; [_entry release]; [super dealloc]; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_stream == nil) | > > > > > | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | - (void)dealloc { if (_stream != nil) [self close]; [_entry release]; if (_archive->_lastReturnedStream == self) _archive->_lastReturnedStream = nil; [_archive release]; [super dealloc]; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_stream == nil) |
︙ | ︙ | |||
513 514 515 516 517 518 519 | { return ((id <OFReadyForWritingObserving>)_stream) .fileDescriptorForWriting; } - (void)close { | | | | | | 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 | { return ((id <OFReadyForWritingObserving>)_stream) .fileDescriptorForWriting; } - (void)close { OFStreamOffset offset; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; _entry.uncompressedSize = _bytesWritten; _entry.compressedSize = _bytesWritten; _entry.CRC16 = _CRC16; offset = [_stream seekToOffset: 0 whence: OFSeekCurrent]; [_stream seekToOffset: _headerOffset whence: OFSeekSet]; [_entry of_writeToStream: _stream encoding: _encoding]; [_stream seekToOffset: offset whence: OFSeekSet]; [_stream release]; _stream = nil; [super close]; } @end |
Modified src/OFLHAArchiveEntry+Private.h from [dc492f96c5] to [521b95b2fc].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * file. */ #import "OFLHAArchive.h" OF_ASSUME_NONNULL_BEGIN | < > | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * file. */ #import "OFLHAArchive.h" OF_ASSUME_NONNULL_BEGIN @interface OFLHAArchiveEntry () - (instancetype)of_init OF_METHOD_FAMILY(init); - (instancetype)of_initWithHeader: (char [_Nonnull 21])header stream: (OFStream *)stream encoding: (OFStringEncoding)encoding OF_METHOD_FAMILY(init) OF_DIRECT; - (void)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding OF_DIRECT; @end OF_ASSUME_NONNULL_END |
Modified src/OFLHAArchiveEntry.h from [e47bb8e429] to [89ea23a8c1].
︙ | ︙ | |||
10 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. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFData; @class OFDate; @class OFMutableArray OF_GENERIC(ObjectType); @class OFNumber; @class OFString; /** * @class OFLHAArchiveEntry OFLHAArchiveEntry.h ObjFW/OFLHAArchiveEntry.h * * @brief A class which represents an entry in an LHA archive. */ | > | > | | > | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | * 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 "OFArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFData; @class OFDate; @class OFMutableArray OF_GENERIC(ObjectType); @class OFNumber; @class OFString; /** * @class OFLHAArchiveEntry OFLHAArchiveEntry.h ObjFW/OFLHAArchiveEntry.h * * @brief A class which represents an entry in an LHA archive. */ @interface OFLHAArchiveEntry: OFObject <OFArchiveEntry, OFCopying, OFMutableCopying> { OFString *_fileName, *_Nullable _directoryName, *_compressionMethod; unsigned long long _compressedSize, _uncompressedSize; OFDate *_modificationDate; uint8_t _headerLevel; uint16_t _CRC16; uint8_t _operatingSystemIdentifier; OFString *_Nullable _fileComment; OFNumber *_Nullable _POSIXPermissions, *_Nullable _ownerAccountID; OFNumber *_Nullable _groupOwnerAccountID; OFString *_Nullable _ownerAccountName; OFString *_Nullable _groupOwnerAccountName; OFMutableArray OF_GENERIC(OFData *) *_extensions; OF_RESERVE_IVARS(OFLHAArchiveEntry, 4) } /** * @brief The compression method of the entry. */ @property (readonly, copy, nonatomic) OFString *compressionMethod; /** * @brief The LHA level of the file. */ @property (readonly, nonatomic) uint8_t headerLevel; /** * @brief The CRC16 of the file. */ @property (readonly, nonatomic) uint16_t CRC16; /** * @brief The operating system identifier of the file. */ @property (readonly, nonatomic) uint8_t operatingSystemIdentifier; /** * @brief The LHA extensions of the file. */ @property (readonly, copy, nonatomic) OFArray OF_GENERIC(OFData *) *extensions; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END #import "OFMutableLHAArchiveEntry.h" |
Modified src/OFLHAArchiveEntry.m from [45c1be7d3b] to [b338459827].
︙ | ︙ | |||
109 110 111 112 113 114 115 | length: extension.count - 1]; } static void parsePermissionsExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { | | | | | | > | | | | | | | | | | > | > | | | | | | | | 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 | length: extension.count - 1]; } static void parsePermissionsExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { uint16_t POSIXPermissions; if (extension.count != 3) @throw [OFInvalidFormatException exception]; memcpy(&POSIXPermissions, (char *)extension.items + 1, 2); POSIXPermissions = OFFromLittleEndian16(POSIXPermissions); [entry->_POSIXPermissions release]; entry->_POSIXPermissions = nil; entry->_POSIXPermissions = [[OFNumber alloc] initWithUnsignedShort: POSIXPermissions]; } static void parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { uint16_t ownerAccountID, groupOwnerAccountID; if (extension.count != 5) @throw [OFInvalidFormatException exception]; memcpy(&groupOwnerAccountID, (char *)extension.items + 1, 2); groupOwnerAccountID = OFFromLittleEndian16(groupOwnerAccountID); memcpy(&ownerAccountID, (char *)extension.items + 3, 2); ownerAccountID = OFFromLittleEndian16(ownerAccountID); [entry->_groupOwnerAccountID release]; entry->_groupOwnerAccountID = nil; [entry->_ownerAccountID release]; entry->_ownerAccountID = nil; entry->_groupOwnerAccountID = [[OFNumber alloc] initWithUnsignedShort: groupOwnerAccountID]; entry->_ownerAccountID = [[OFNumber alloc] initWithUnsignedShort: ownerAccountID]; } static void parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { [entry->_groupOwnerAccountName release]; entry->_groupOwnerAccountName = nil; entry->_groupOwnerAccountName = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parseOwnerExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { [entry->_ownerAccountName release]; entry->_ownerAccountName = nil; entry->_ownerAccountName = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parseModificationDateExtension(OFLHAArchiveEntry *entry, OFData *extension, |
︙ | ︙ | |||
299 300 301 302 303 304 305 | *fileName = cString + pos; *fileNameLength = length - pos; *directoryName = cString; *directoryNameLength = pos; } | < < < < < | < | | 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 | *fileName = cString + pos; *fileNameLength = length - pos; *directoryName = cString; *directoryNameLength = pos; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_init { self = [super init]; @try { _compressionMethod = @"-lh0-"; _modificationDate = [[OFDate alloc] init]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
339 340 341 342 343 344 345 346 | uint32_t date; _compressionMethod = [[OFString alloc] initWithCString: header + 2 encoding: OFStringEncodingASCII length: 5]; memcpy(&_compressedSize, header + 7, 4); | > > > > | > | > | | | 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 | uint32_t date; _compressionMethod = [[OFString alloc] initWithCString: header + 2 encoding: OFStringEncodingASCII length: 5]; if (_compressedSize > UINT32_MAX || _uncompressedSize > UINT32_MAX) @throw [OFOutOfRangeException exception]; memcpy(&_compressedSize, header + 7, 4); _compressedSize = OFFromLittleEndian32((uint32_t)_compressedSize); memcpy(&_uncompressedSize, header + 11, 4); _uncompressedSize = OFFromLittleEndian32((uint32_t)_uncompressedSize); memcpy(&date, header + 15, 4); date = OFFromLittleEndian32(date); _headerLevel = header[20]; _extensions = [[OFMutableArray alloc] init]; switch (_headerLevel) { case 0: case 1:; void *pool = objc_autoreleasePoolPush(); uint8_t fileNameLength; OFString *tmp; _modificationDate = [parseMSDOSDate(date) retain]; fileNameLength = [stream readInt8]; tmp = [stream readStringWithLength: fileNameLength encoding: encoding]; tmp = [tmp stringByReplacingOccurrencesOfString: @"\\" withString: @"/"]; _fileName = [tmp copy]; _CRC16 = [stream readLittleEndianInt16]; if (_headerLevel == 1) { _operatingSystemIdentifier = [stream readInt8]; readExtensions(self, stream, encoding, false); } objc_autoreleasePoolPop(pool); break; case 2: _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: date]; _CRC16 = [stream readLittleEndianInt16]; _operatingSystemIdentifier = [stream readInt8]; readExtensions(self, stream, encoding, true); |
︙ | ︙ | |||
412 413 414 415 416 417 418 | } - (void)dealloc { [_compressionMethod release]; [_fileName release]; [_directoryName release]; | | | | | | | | | | | | | | | < | 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 | } - (void)dealloc { [_compressionMethod release]; [_fileName release]; [_directoryName release]; [_modificationDate release]; [_fileComment release]; [_POSIXPermissions release]; [_ownerAccountID release]; [_groupOwnerAccountID release]; [_ownerAccountName release]; [_groupOwnerAccountName release]; [_extensions release]; [super dealloc]; } - (id)copy { return [self retain]; } - (id)mutableCopy { OFLHAArchiveEntry *copy = [[OFMutableLHAArchiveEntry alloc] initWithFileName: _fileName]; @try { [copy->_compressionMethod release]; copy->_compressionMethod = nil; [copy->_modificationDate release]; copy->_modificationDate = nil; copy->_directoryName = [_directoryName copy]; copy->_compressionMethod = [_compressionMethod copy]; copy->_compressedSize = _compressedSize; copy->_uncompressedSize = _uncompressedSize; copy->_modificationDate = [_modificationDate copy]; copy->_headerLevel = _headerLevel; copy->_CRC16 = _CRC16; copy->_operatingSystemIdentifier = _operatingSystemIdentifier; copy->_fileComment = [_fileComment copy]; copy->_POSIXPermissions = [_POSIXPermissions retain]; copy->_ownerAccountID = [_ownerAccountID retain]; copy->_groupOwnerAccountID = [_groupOwnerAccountID retain]; copy->_ownerAccountName = [_ownerAccountName copy]; copy->_groupOwnerAccountName = [_groupOwnerAccountName copy]; copy->_extensions = [_extensions copy]; } @catch (id e) { [copy release]; @throw e; } return copy; |
︙ | ︙ | |||
478 479 480 481 482 483 484 | } - (OFString *)compressionMethod { return _compressionMethod; } | | | | | | 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 | } - (OFString *)compressionMethod { return _compressionMethod; } - (unsigned long long)compressedSize { return _compressedSize; } - (unsigned long long)uncompressedSize { return _uncompressedSize; } - (OFDate *)modificationDate { return _modificationDate; } - (uint8_t)headerLevel { return _headerLevel; } |
︙ | ︙ | |||
513 514 515 516 517 518 519 | } - (OFString *)fileComment { return _fileComment; } | | | | | | | | | | | < < < < < | 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 | } - (OFString *)fileComment { return _fileComment; } - (OFNumber *)POSIXPermissions { return _POSIXPermissions; } - (OFNumber *)ownerAccountID { return _ownerAccountID; } - (OFNumber *)groupOwnerAccountID { return _groupOwnerAccountID; } - (OFString *)ownerAccountName { return _ownerAccountName; } - (OFString *)groupOwnerAccountName { return _groupOwnerAccountName; } - (OFArray OF_GENERIC(OFData *) *)extensions { return _extensions; } |
︙ | ︙ | |||
567 568 569 570 571 572 573 | OFStringEncodingASCII] != 5) @throw [OFInvalidArgumentException exception]; getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength, &directoryName, &directoryNameLength); if (fileNameLength > UINT16_MAX - 3 || | | > | | | > | 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 | OFStringEncodingASCII] != 5) @throw [OFInvalidArgumentException exception]; getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength, &directoryName, &directoryNameLength); if (fileNameLength > UINT16_MAX - 3 || directoryNameLength > UINT16_MAX - 3 || _compressedSize > UINT32_MAX || _uncompressedSize > UINT32_MAX) @throw [OFOutOfRangeException exception]; /* Length. Filled in after we're done. */ [data increaseCountBy: 2]; [data addItems: [_compressionMethod cStringWithEncoding: OFStringEncodingASCII] count: 5]; tmp32 = OFToLittleEndian32((uint32_t)_compressedSize); [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OFToLittleEndian32((uint32_t)_uncompressedSize); [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OFToLittleEndian32( (uint32_t)_modificationDate.timeIntervalSince1970); [data addItems: &tmp32 count: sizeof(tmp32)]; /* Reserved */ [data increaseCountBy: 1]; /* Header level */ [data addItem: "\x02"]; |
︙ | ︙ | |||
631 632 633 634 635 636 637 | tmp16 = OFToLittleEndian16((uint16_t)fileCommentLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x3F"]; [data addItems: [_fileComment cStringWithEncoding: encoding] count: fileCommentLength]; } | | > | | | | > | | | | | | | > | | | | | | | < < | < < < < | < < < | 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 | tmp16 = OFToLittleEndian16((uint16_t)fileCommentLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x3F"]; [data addItems: [_fileComment cStringWithEncoding: encoding] count: fileCommentLength]; } if (_POSIXPermissions != nil) { tmp16 = OFToLittleEndian16(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; tmp16 = OFToLittleEndian16(_POSIXPermissions.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_ownerAccountID != nil || _groupOwnerAccountID != nil) { if (_ownerAccountID == nil || _groupOwnerAccountID == nil) @throw [OFInvalidArgumentException exception]; tmp16 = OFToLittleEndian16(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x51"]; tmp16 = OFToLittleEndian16( _groupOwnerAccountID.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; tmp16 = OFToLittleEndian16(_ownerAccountID.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_groupOwnerAccountName != nil) { size_t length = [_groupOwnerAccountName cStringLengthWithEncoding: encoding]; if (length > UINT16_MAX - 3) @throw [OFOutOfRangeException exception]; tmp16 = OFToLittleEndian16((uint16_t)length + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x52"]; [data addItems: [_groupOwnerAccountName cStringWithEncoding: encoding] count: length]; } if (_ownerAccountName != nil) { size_t length = [_ownerAccountName cStringLengthWithEncoding: encoding]; if (length > UINT16_MAX - 3) @throw [OFOutOfRangeException exception]; tmp16 = OFToLittleEndian16((uint16_t)length + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x53"]; [data addItems: [_ownerAccountName cStringWithEncoding: encoding] count: length]; } for (OFData *extension in _extensions) { size_t extensionLength = extension.count; if (extension.itemSize != 1) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
731 732 733 734 735 736 737 | objc_autoreleasePoolPop(pool); } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); | | < > > > > > > | | | | | | | | | < | | > | | 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 | objc_autoreleasePoolPop(pool); } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFString *POSIXPermissions = nil; OFString *extensions = [_extensions.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; OFString *ret; if (_POSIXPermissions != nil) POSIXPermissions = [OFString stringWithFormat: @"%ho", _POSIXPermissions.unsignedShortValue]; ret = [OFString stringWithFormat: @"<%@:\n" @"\tFile name = %@\n" @"\tCompression method = %@\n" @"\tCompressed size = %llu\n" @"\tUncompressed size = %llu\n" @"\tModification date = %@\n" @"\tHeader level = %u\n" @"\tCRC16 = %04" @PRIX16 @"\n" @"\tOperating system identifier = %c\n" @"\tComment = %@\n" @"\tPOSIX permissions = %@\n" @"\tOwner account ID = %@\n" @"\tGroup owner account ID = %@\n" @"\tOwner account name = %@\n" @"\tGroup owner accounut name = %@\n" @"\tExtensions: %@" @">", self.class, self.fileName, _compressionMethod, _compressedSize, _uncompressedSize, _modificationDate, _headerLevel, _CRC16, _operatingSystemIdentifier, _fileComment, POSIXPermissions, _ownerAccountID, _groupOwnerAccountID, _ownerAccountName, _groupOwnerAccountName, extensions]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFLocale.h from [fcc8f077d2] to [ca12b9c93f].
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * @def OF_LOCALIZED * * @brief Returns the localized string for the specified ID with the specified * arguments inserted. * * @param ID The ID of the localized string to retrieve * @return The localized string with the specified arguments replaced */ #define OF_LOCALIZED(ID, ...) \ [[OFLocale currentLocale] localizedStringForID: ID \ fallback: __VA_ARGS__, nil] @class OFMutableArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); /** * @class OFLocale OFLocale.h ObjFW/OFLocale.h * * @brief A class for querying the locale and retrieving localized strings. */ OF_SUBCLASSING_RESTRICTED @interface OFLocale: OFObject { | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | * @def OF_LOCALIZED * * @brief Returns the localized string for the specified ID with the specified * arguments inserted. * * @param ID The ID of the localized string to retrieve * @return The localized string with the specified arguments replaced * @throw OFInvalidFormatException The string (either the fallback or the * localized one) contains an invalid format */ #define OF_LOCALIZED(ID, ...) \ [[OFLocale currentLocale] localizedStringForID: ID \ fallback: __VA_ARGS__, nil] @class OFMutableArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); /** * @class OFLocale OFLocale.h ObjFW/OFLocale.h * * @brief A class for querying the locale and retrieving localized strings. */ OF_SUBCLASSING_RESTRICTED @interface OFLocale: OFObject { OFString *_Nullable _languageCode, *_Nullable _countryCode; OFStringEncoding _encoding; OFString *_decimalSeparator; OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *) *_localizedStrings; } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nullable, nonatomic) OFLocale *currentLocale; @property (class, readonly, nullable, nonatomic) OFString *languageCode; @property (class, readonly, nullable, nonatomic) OFString *countryCode; @property (class, readonly, nonatomic) OFStringEncoding encoding; @property (class, readonly, nullable, nonatomic) OFString *decimalSeparator; #endif /** * @brief The language code of the locale for messages. * * If the language is unknown, it is `nil`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *languageCode; /** * @brief The country code of the locale for messages. * * If the territory is unknown, it is `nil`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *countryCode; /** * @brief The native 8-bit string encoding of the locale for messages. * * This is useful to encode strings correctly for passing them to operating * system calls. * * If the native 8-bit encoding is unknown, UTF-8 is assumed. */ @property (readonly, nonatomic) OFStringEncoding encoding; /** * @brief The decimal separator of the locale. */ @property (readonly, nonatomic) OFString *decimalSeparator; /** * @brief Returns the current OFLocale. * * @warning If you don't use @ref OFApplication, this might be `nil`! In this * case, you need to manually allocate an instance and call * @ref init once. * * @return The current OFLocale instance */ + (nullable OFLocale *)currentLocale; /** * @brief Returns the language code of the locale. * * If the language is unknown, `nil` is returned. * * @return The language code of the locale. */ + (nullable OFString *)languageCode; /** * @brief Returns the country code of the locale. * * If the country is unknown, `nil` is returned. * * @return The country code of the locale. */ + (nullable OFString *)countryCode; /** * @brief Returns the native 8-bit string encoding for the locale. * * This is useful to encode strings correctly for passing them to operating * system calls. * * If the native 8-bit encoding is unknown, UTF-8 is assumed. * * @return The native 8-bit string encoding for the locale */ + (OFStringEncoding)encoding; /** * @brief Returns the decimal point of the system's locale. * * @return The decimal point of the system's locale */ + (nullable OFString *)decimalSeparator; #ifdef OF_HAVE_FILES /** * @brief Adds a directory to scan for localizations. * * @param path The path to the directory to scan for localizations */ + (void)addLocalizationDirectory: (OFString *)path; #endif /** * @brief Initializes the current OFLocale. * * @warning This sets the locale via `setlocale()`! * * @warning You should never call this yourself, except if you do not use * @ref OFApplication. In this case, you need to allocate exactly one * instance of OFLocale, which will become the current locale, and * call this method. */ - (instancetype)init; #ifdef OF_HAVE_FILES /** * @brief Adds a directory to scan for localizations. * * @param path The path to the directory to scan for localizations */ - (void)addLocalizationDirectory: (OFString *)path; #endif /** * @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`, 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 localization 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 |
︙ | ︙ | |||
200 201 202 203 204 205 206 | * * @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 | | > > | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | * * @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 localization 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 * @throw OFInvalidFormatException The string (either the fallback or the * localized one) contains an invalid format */ - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (id)fallback arguments: (va_list)arguments; @end OF_ASSUME_NONNULL_END |
Modified src/OFLocale.m from [ccac2d9a08] to [e8b5569b76].
︙ | ︙ | |||
36 37 38 39 40 41 42 | static OFLocale *currentLocale = nil; static OFDictionary *operatorPrecedences = nil; #ifndef OF_AMIGAOS static void parseLocale(char *locale, OFStringEncoding *encoding, | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | static OFLocale *currentLocale = nil; static OFDictionary *operatorPrecedences = nil; #ifndef OF_AMIGAOS static void parseLocale(char *locale, OFStringEncoding *encoding, OFString **languageCode, OFString **countryCode) { locale = OFStrDup(locale); @try { OFStringEncoding enc = OFStringEncodingASCII; char *tmp; |
︙ | ︙ | |||
61 62 63 64 65 66 67 | *encoding = OFStringEncodingParseName( [OFString stringWithCString: tmp encoding: enc]); } @catch (OFInvalidArgumentException *e) { } } | | | > | | | | | | 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 | *encoding = OFStringEncodingParseName( [OFString stringWithCString: tmp encoding: enc]); } @catch (OFInvalidArgumentException *e) { } } /* Country code */ if ((tmp = strrchr(locale, '_')) != NULL) { *tmp++ = '\0'; if (countryCode != NULL) *countryCode = [OFString stringWithCString: tmp encoding: enc]; } if (languageCode != NULL) *languageCode = [OFString stringWithCString: locale encoding: enc]; } @finally { OFFreeMemory(locale); } } #endif static bool |
︙ | ︙ | |||
299 300 301 302 303 304 305 | [string makeImmutable]; return string; } @implementation OFLocale | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | [string makeImmutable]; return string; } @implementation OFLocale @synthesize languageCode = _languageCode, countryCode = _countryCode; @synthesize encoding = _encoding, decimalSeparator = _decimalSeparator; + (void)initialize { OFNumber *one, *two, *three, *four; if (self != [OFLocale class]) return; |
︙ | ︙ | |||
336 337 338 339 340 341 342 | } + (OFLocale *)currentLocale { return currentLocale; } | | | | | | | | | | | | | | | 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 | } + (OFLocale *)currentLocale { return currentLocale; } + (OFString *)languageCode { return currentLocale.languageCode; } + (OFString *)countryCode { return currentLocale.countryCode; } + (OFStringEncoding)encoding { return currentLocale.encoding; } + (OFString *)decimalSeparator { return currentLocale.decimalSeparator; } #ifdef OF_HAVE_FILES + (void)addLocalizationDirectory: (OFString *)path { [currentLocale addLocalizationDirectory: path]; } #endif - (instancetype)init { self = [super init]; @try { #ifndef OF_AMIGAOS char *locale, *messagesLocale = NULL; if (currentLocale != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _encoding = OFStringEncodingUTF8; _decimalSeparator = @"."; _localizedStrings = [[OFMutableArray alloc] init]; if ((locale = setlocale(LC_ALL, "")) != NULL) _decimalSeparator = [[OFString alloc] initWithCString: localeconv()->decimal_point encoding: _encoding]; # ifdef LC_MESSAGES messagesLocale = setlocale(LC_MESSAGES, ""); # endif if (messagesLocale == NULL) messagesLocale = locale; if (messagesLocale != NULL) { void *pool = objc_autoreleasePoolPush(); parseLocale(messagesLocale, &_encoding, &_languageCode, &_countryCode); [_languageCode retain]; [_countryCode retain]; objc_autoreleasePoolPop(pool); } #else void *pool = objc_autoreleasePoolPush(); char buffer[32]; struct Locale *locale; |
︙ | ︙ | |||
435 436 437 438 439 440 441 | } else _encoding = OFStringEncodingISO8859_1; /* * Get it via localeconv() instead of from the Locale struct, * to make sure we and printf etc. have the same expectations. */ | | | | | | | | | 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 | } else _encoding = OFStringEncodingISO8859_1; /* * Get it via localeconv() instead of from the Locale struct, * to make sure we and printf etc. have the same expectations. */ _decimalSeparator = [[OFString alloc] initWithCString: localeconv()->decimal_point encoding: _encoding]; _localizedStrings = [[OFMutableArray alloc] init]; if (GetVar("Language", buffer, sizeof(buffer), 0) > 0) _languageCode = [[OFString alloc] initWithCString: buffer encoding: _encoding]; if ((locale = OpenLocale(NULL)) != NULL) { @try { uint32_t countryCode; size_t length; countryCode = OFToBigEndian32(locale->loc_CountryCode); for (length = 0; length < 4; length++) if (((char *)&countryCode)[length] == 0) break; _countryCode = [[OFString alloc] initWithCString: (char *)&countryCode encoding: _encoding length: length]; } @finally { CloseLocale(locale); } } |
︙ | ︙ | |||
481 482 483 484 485 486 487 | currentLocale = self; return self; } - (void)dealloc { | | | | | | | | | | | | | > | | > | | | | | 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 | currentLocale = self; return self; } - (void)dealloc { [_languageCode release]; [_countryCode release]; [_decimalSeparator release]; [_localizedStrings release]; [super dealloc]; } #ifdef OF_HAVE_FILES - (void)addLocalizationDirectory: (OFString *)path { void *pool; OFString *mapPath, *languageCode, *countryCode, *localizationFile; OFDictionary *map; if (_languageCode == nil) return; pool = objc_autoreleasePoolPush(); mapPath = [path stringByAppendingPathComponent: @"localizations.json"]; @try { map = [[OFString stringWithContentsOfFile: mapPath] objectByParsingJSON]; } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } languageCode = _languageCode.lowercaseString; countryCode = _countryCode.lowercaseString; if (countryCode == nil) countryCode = @""; localizationFile = [[map objectForKey: languageCode] objectForKey: countryCode]; if (localizationFile == nil) localizationFile = [[map objectForKey: languageCode] objectForKey: @""]; if (localizationFile == nil) { objc_autoreleasePoolPop(pool); return; } localizationFile = [path stringByAppendingPathComponent: [localizationFile stringByAppendingString: @".json"]]; [_localizedStrings addObject: [[OFString stringWithContentsOfFile: localizationFile] objectByParsingJSON]]; objc_autoreleasePoolPop(pool); } #endif - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (id)fallback, ... |
︙ | ︙ |
Modified src/OFLocking.h from [ae2e49ea45] to [155544ed9e].
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | /** * @brief The name of the lock. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *name; /** * @brief Locks the lock. */ - (void)lock; /** * @brief Tries to lock the lock. * * @return A boolean whether the lock could be locked */ - (bool)tryLock; /** * @brief Unlocks the lock. */ - (void)unlock; @end OF_ASSUME_NONNULL_END | > > > > > > > | 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 | /** * @brief The name of the lock. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *name; /** * @brief Locks the lock. * * @throw OFLockFailedException Acquiring the lock failed */ - (void)lock; /** * @brief Tries to lock the lock. * * @return A boolean whether the lock could be locked * * @throw OFLockFailedException The lock could not be acquired for another * reason than it already being held */ - (bool)tryLock; /** * @brief Unlocks the lock. * * @throw OFUnlockFailedException Releasing the lock failed */ - (void)unlock; @end OF_ASSUME_NONNULL_END |
Modified src/OFMapTable.h from [db5052bd42] to [382835ac81].
︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 | /** * @class OFMapTableEnumerator OFMapTable.h ObjFW/OFMapTable.h * * @brief A class which provides methods to enumerate through an OFMapTable's * keys or objects. */ @interface OFMapTableEnumerator: OFObject { OFMapTable *_mapTable; struct OFMapTableBucket *_Nonnull *_Nullable _buckets; uint32_t _capacity; unsigned long _mutations, *_Nullable _mutationsPtr, _position; } | > > > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | /** * @class OFMapTableEnumerator OFMapTable.h ObjFW/OFMapTable.h * * @brief A class which provides methods to enumerate through an OFMapTable's * keys or objects. */ #ifndef OF_MAP_TABLE_M OF_SUBCLASSING_RESTRICTED #endif @interface OFMapTableEnumerator: OFObject { OFMapTable *_mapTable; struct OFMapTableBucket *_Nonnull *_Nullable _buckets; uint32_t _capacity; unsigned long _mutations, *_Nullable _mutationsPtr, _position; } |
︙ | ︙ |
Modified src/OFMapTable.m from [155910f8b1] to [61602c79fe].
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | * 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 <stdlib.h> #include <string.h> #include <assert.h> | > > | 8 9 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. */ #define OF_MAP_TABLE_M #include "config.h" #include <stdlib.h> #include <string.h> #include <assert.h> |
︙ | ︙ |
Modified src/OFMemoryStream.m from [1697ea3e2b] to [d9d07c7da0].
︙ | ︙ | |||
42 43 44 45 46 47 48 | - (instancetype)initWithMemoryAddress: (void *)address size: (size_t)size writable: (bool)writable { self = [super init]; @try { | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | - (instancetype)initWithMemoryAddress: (void *)address size: (size_t)size writable: (bool)writable { self = [super init]; @try { if (size > SSIZE_MAX || (ssize_t)size != (OFStreamOffset)size) @throw [OFOutOfRangeException exception]; _address = address; _size = size; _writable = writable; } @catch (id e) { [self release]; |
︙ | ︙ | |||
97 98 99 100 101 102 103 | } - (bool)lowlevelIsAtEndOfStream { return (_position == _size); } | | > | | | | | | | | 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 | } - (bool)lowlevelIsAtEndOfStream { return (_position == _size); } - (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset whence: (OFSeekWhence)whence { OFStreamOffset new; switch (whence) { case OFSeekSet: new = offset; break; case OFSeekCurrent: new = (OFStreamOffset)_position + offset; break; case OFSeekEnd: new = (OFStreamOffset)_size + offset; break; default: @throw [OFInvalidArgumentException exception]; } if (new < 0 || new > (OFStreamOffset)_size) @throw [OFSeekFailedException exceptionWithStream: self offset: offset whence: whence errNo: EINVAL]; return (_position = (size_t)new); } @end |
Modified src/OFMessagePackExtension.h from [45f0ba641f] to [99c89d24f1].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 | /** * @class OFMessagePackExtension \ * OFMessagePackExtension.h ObjFW/OFMessagePackExtension.h * * @brief A class for representing the MessagePack extension type. */ @interface OFMessagePackExtension: OFObject <OFMessagePackRepresentation, OFCopying> { int8_t _type; OFData *_data; | > < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** * @class OFMessagePackExtension \ * OFMessagePackExtension.h ObjFW/OFMessagePackExtension.h * * @brief A class for representing the MessagePack extension type. */ OF_SUBCLASSING_RESTRICTED @interface OFMessagePackExtension: OFObject <OFMessagePackRepresentation, OFCopying> { int8_t _type; OFData *_data; } /** * @brief The MessagePack extension type. */ @property (readonly, nonatomic) int8_t type; |
︙ | ︙ |
Modified src/OFMessagePackExtension.m from [7009717fd9] to [a3971287d8].
︙ | ︙ | |||
170 171 172 173 174 175 176 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); | | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddByte(&hash, (uint8_t)_type); OFHashAddHash(&hash, _data.hash); OFHashFinalize(&hash); return hash; } |
︙ | ︙ |
Modified src/OFMethodSignature.h from [6c7eab90df] to [996cafd8b2].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 | @class OFMutableData; /** * @class OFMethodSignature OFMethodSignature.h ObjFW/OFMethodSignature.h * * @brief A class for parsing type encodings and accessing them. */ @interface OFMethodSignature: OFObject { char *_types; OFMutableData *_typesPointers, *_offsets; | > < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | @class OFMutableData; /** * @class OFMethodSignature OFMethodSignature.h ObjFW/OFMethodSignature.h * * @brief A class for parsing type encodings and accessing them. */ OF_SUBCLASSING_RESTRICTED @interface OFMethodSignature: OFObject { char *_types; OFMutableData *_typesPointers, *_offsets; } /** * @brief The number of arguments of the method. */ @property (readonly, nonatomic) size_t numberOfArguments; |
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | @property (readonly, nonatomic) size_t frameLength; /** * @brief Creates a new OFMethodSignature with the specified ObjC types. * * @param types The ObjC types of the method * @return A new, autoreleased OFMethodSignature */ + (instancetype)signatureWithObjCTypes: (const char *)types; /** * @brief Initializes an already allocated OFMethodSignature with the specified * ObjC types. * * @param types The ObjC types of the method * @return An Initialized OFMethodSignature */ - (instancetype)initWithObjCTypes: (const char *)types; /** * @brief Returns the ObjC type for the argument at the specified index. * * @param index The index of the argument for which to return the ObjC type | > > | 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 | @property (readonly, nonatomic) size_t frameLength; /** * @brief Creates a new OFMethodSignature with the specified ObjC types. * * @param types The ObjC types of the method * @return A new, autoreleased OFMethodSignature * @throw OFInvalidFormatException The type encoding is invalid */ + (instancetype)signatureWithObjCTypes: (const char *)types; /** * @brief Initializes an already allocated OFMethodSignature with the specified * ObjC types. * * @param types The ObjC types of the method * @return An Initialized OFMethodSignature * @throw OFInvalidFormatException The type encoding is invalid */ - (instancetype)initWithObjCTypes: (const char *)types; /** * @brief Returns the ObjC type for the argument at the specified index. * * @param index The index of the argument for which to return the ObjC type |
︙ | ︙ | |||
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | extern "C" { #endif /** * @brief Returns the size for the specified type encoding. * * @param type The type encoding to return the size for * @return The size for the specified type encoding */ extern size_t OFSizeOfTypeEncoding(const char *type); /** * @brief Returns the alignment for the specified type encoding. * * @param type The type encoding to return the alignment for * @return The alignment for the specified type encoding */ extern size_t OFAlignmentOfTypeEncoding(const char *type); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END | > > | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | extern "C" { #endif /** * @brief Returns the size for the specified type encoding. * * @param type The type encoding to return the size for * @return The size for the specified type encoding * @throw OFInvalidFormatException The type encoding is invalid */ extern size_t OFSizeOfTypeEncoding(const char *type); /** * @brief Returns the alignment for the specified type encoding. * * @param type The type encoding to return the alignment for * @return The alignment for the specified type encoding * @throw OFInvalidFormatException The type encoding is invalid */ extern size_t OFAlignmentOfTypeEncoding(const char *type); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFMethodSignature.m from [e6d0a405ec] to [9c702fcecb].
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 | (*type)++; (*length)--; return alignment; } static size_t alignmentOfEncoding(const char **type, size_t *length, bool inStruct) { size_t alignment; if (*length == 0) @throw [OFInvalidFormatException exception]; | > > > > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | (*type)++; (*length)--; return alignment; } static size_t #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 7 /* Work around an ICE in Clang 3.7.0 on Windows/x86 */ __attribute__((__optnone__)) #endif alignmentOfEncoding(const char **type, size_t *length, bool inStruct) { size_t alignment; if (*length == 0) @throw [OFInvalidFormatException exception]; |
︙ | ︙ |
Added src/OFMutableArchiveEntry.h version [ffb170561c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Copyright (c) 2008-2022 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 "OFArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN /** * @protocol OFMutableArchiveEntry \ * OFMutableArchiveEntry.h ObjFW/OFMutableArchiveEntry.h * * @brief A class which represents a mutable entry in an archive. */ @protocol OFMutableArchiveEntry <OFArchiveEntry> /** * @brief The file name of the entry. */ @property (readwrite, copy, nonatomic) OFString *fileName; /** * @brief The compressed size of the entry's file. */ @property (readwrite, nonatomic) unsigned long long compressedSize; /** * @brief The uncompressed size of the entry's file. */ @property (readwrite, nonatomic) unsigned long long uncompressedSize; @optional /** * @brief The modification date of the file. */ @property (readwrite, retain, nonatomic) OFDate *modificationDate; /** * @brief The comment of the entry's file. */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *fileComment; /** * @brief The POSIX permissions of the file. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFNumber *POSIXPermissions; /** * @brief The file owner's account ID. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFNumber *ownerAccountID; /** * @brief The file owner's group account ID. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFNumber *groupOwnerAccountID; /** * @brief The file owner's account name. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFString *ownerAccountName; /** * @brief The file owner's group account name. */ @property OF_NULLABLE_PROPERTY (readwrite, retain, nonatomic) OFString *groupOwnerAccountName; @end OF_ASSUME_NONNULL_END #import "OFMutableArchiveEntry.h" |
Modified src/OFMutableArray.m from [8e711f8f4a] to [ba1c079bde].
︙ | ︙ | |||
377 378 379 380 381 382 383 | return; [self removeObjectAtIndex: count - 1]; } - (void)removeAllObjects { | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | return; [self removeObjectAtIndex: count - 1]; } - (void)removeAllObjects { [self removeObjectsInRange: OFMakeRange(0, self.count)]; } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (OFArrayReplaceBlock)block { [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { |
︙ | ︙ |
Modified src/OFMutableData.h from [5eba71457e] to [23548715da].
︙ | ︙ | |||
14 15 16 17 18 19 20 | */ #import "OFData.h" OF_ASSUME_NONNULL_BEGIN @class OFString; | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | */ #import "OFData.h" OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFURI; /** * @class OFMutableData OFMutableData.h ObjFW/OFMutableData.h * * @brief A class for storing and manipulating arbitrary data in an array. */ @interface OFMutableData: OFData |
︙ | ︙ | |||
200 201 202 203 204 205 206 | /** * @brief Removes all items. */ - (void)removeAllItems; /** | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 | /** * @brief Removes all items. */ - (void)removeAllItems; /** * @brief Converts the mutable data to an immutable data. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END |
Modified src/OFMutableData.m from [2aa51e2819] to [b4151ce5ed].
︙ | ︙ | |||
240 241 242 243 244 245 246 | memset(_items + _count * _itemSize, '\0', count * _itemSize); _count += count; } - (void)removeItemAtIndex: (size_t)idx { | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | memset(_items + _count * _itemSize, '\0', count * _itemSize); _count += count; } - (void)removeItemAtIndex: (size_t)idx { [self removeItemsInRange: OFMakeRange(idx, 1)]; } - (void)removeItemsInRange: (OFRange)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; |
︙ | ︙ |
Modified src/OFMutableLHAArchiveEntry.h from [4253f691f5] to [5bfb2f1e47].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | * 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 "OFLHAArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFMutableLHAArchiveEntry \ * OFMutableLHAArchiveEntry.h ObjFW/OFMutableLHAArchiveEntry.h * * @brief A class which represents a mutable entry in an LHA archive. */ | > | < < < < < < < < < < < < < < < < < < < < | | < | < < | < < < < | < < < < | < < | | < < | < < < < < | < | > < > | 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 | * 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 "OFLHAArchiveEntry.h" #import "OFMutableArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFMutableLHAArchiveEntry \ * OFMutableLHAArchiveEntry.h ObjFW/OFMutableLHAArchiveEntry.h * * @brief A class which represents a mutable entry in an LHA archive. */ @interface OFMutableLHAArchiveEntry: OFLHAArchiveEntry <OFMutableArchiveEntry> { OF_RESERVE_IVARS(OFMutableLHAArchiveEntry, 4) } /** * @brief The compression method of the entry. */ @property (readwrite, copy, nonatomic) OFString *compressionMethod; /** * @brief The LHA level of the file. */ @property (readwrite, nonatomic) uint8_t headerLevel; /** * @brief The CRC16 of the file. */ @property (readwrite, nonatomic) uint16_t CRC16; /** * @brief The operating system identifier of the file. */ @property (readwrite, nonatomic) uint8_t operatingSystemIdentifier; /** * @brief The LHA extensions of the file. */ @property (readwrite, copy, nonatomic) OFArray OF_GENERIC(OFData *) *extensions; /** * @brief Creates a new OFMutableLHAArchiveEntry with the specified file name. * * @param fileName The file name for the OFLHAArchiveEntry * @return A new, autoreleased OFLHAArchiveEntry */ + (instancetype)entryWithFileName: (OFString *)fileName; /** * @brief Initializes an already allocated OFMutableLHAArchiveEntry with the * specified file name. * * @param fileName The file name for the OFLHAArchiveEntry * @return An initialized OFLHAArchiveEntry */ - (instancetype)initWithFileName: (OFString *)fileName; /** * @brief Converts the OFMutableLHAArchiveEntry to an immutable * OFLHAArchiveEntry. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END |
Modified src/OFMutableLHAArchiveEntry.m from [8d9a6a0cb1] to [84adbb8df8].
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFMutableLHAArchiveEntry.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #import "OFNumber.h" #import "OFString.h" @implementation OFMutableLHAArchiveEntry | > | | > > | > > > > > > > > > > > > > > > > > > | 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 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFMutableLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #import "OFNumber.h" #import "OFString.h" @implementation OFMutableLHAArchiveEntry @dynamic fileName, compressionMethod, compressedSize, uncompressedSize; @dynamic modificationDate, headerLevel, CRC16, operatingSystemIdentifier; @dynamic fileComment, POSIXPermissions, ownerAccountID, groupOwnerAccountID; @dynamic ownerAccountName, groupOwnerAccountName, extensions; + (instancetype)entryWithFileName: (OFString *)fileName { return [[[self alloc] initWithFileName: fileName] autorelease]; } - (instancetype)initWithFileName: (OFString *)fileName { self = [super of_init]; @try { _fileName = [fileName copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (id)copy { OFMutableLHAArchiveEntry *copy = [self mutableCopy]; [copy makeImmutable]; |
︙ | ︙ | |||
50 51 52 53 54 55 56 | - (void)setCompressionMethod: (OFString *)compressionMethod { OFString *old = _compressionMethod; _compressionMethod = [compressionMethod copy]; [old release]; } | | | | | | | 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 | - (void)setCompressionMethod: (OFString *)compressionMethod { OFString *old = _compressionMethod; _compressionMethod = [compressionMethod copy]; [old release]; } - (void)setCompressedSize: (unsigned long long)compressedSize { _compressedSize = compressedSize; } - (void)setUncompressedSize: (unsigned long long)uncompressedSize { _uncompressedSize = uncompressedSize; } - (void)setModificationDate: (OFDate *)modificationDate { OFDate *old = _modificationDate; _modificationDate = [modificationDate retain]; [old release]; } - (void)setHeaderLevel: (uint8_t)headerLevel { _headerLevel = headerLevel; } |
︙ | ︙ | |||
89 90 91 92 93 94 95 | - (void)setFileComment: (OFString *)fileComment { OFString *old = _fileComment; _fileComment = [fileComment copy]; [old release]; } | | | | | | | < < < < < < | | < | | | | | | | | | 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 | - (void)setFileComment: (OFString *)fileComment { OFString *old = _fileComment; _fileComment = [fileComment copy]; [old release]; } - (void)setPOSIXPermissions: (OFNumber *)POSIXPermissions { OFNumber *old = _POSIXPermissions; _POSIXPermissions = [POSIXPermissions retain]; [old release]; } - (void)setOwnerAccountID: (OFNumber *)ownerAccountID { OFNumber *old = _ownerAccountID; _ownerAccountID = [ownerAccountID retain]; [old release]; } - (void)setGroupOwnerAccountID: (OFNumber *)groupOwnerAccountID { OFNumber *old = _groupOwnerAccountID; _groupOwnerAccountID = [groupOwnerAccountID retain]; [old release]; } - (void)setOwnerAccountName: (OFString *)ownerAccountName { OFString *old = _ownerAccountName; _ownerAccountName = [ownerAccountName copy]; [old release]; } - (void)setGroupOwnerAccountName: (OFString *)groupOwnerAccountName { OFString *old = _groupOwnerAccountName; _groupOwnerAccountName = [groupOwnerAccountName copy]; [old release]; } - (void)setExtensions: (OFArray OF_GENERIC(OFData *) *)extensions { OFArray OF_GENERIC(OFData *) *old = _extensions; _extensions = [extensions copy]; |
︙ | ︙ |
Modified src/OFMutableString.h from [9300a1f2cf] to [f372a7a142].
︙ | ︙ | |||
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 | */ - (void)appendCharacters: (const OFUnichar *)characters length: (size_t)length; /** * @brief Appends a UTF-8 encoded C string to the OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append */ - (void)appendUTF8String: (const char *)UTF8String; /** * @brief Appends a UTF-8 encoded C string with the specified length to the * OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append * @param UTF8StringLength The length of the UTF-8 encoded C string */ - (void)appendUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; /** * @brief Appends a C string with the specified encoding to the OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string */ - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding; /** * @brief Appends a C string with the specified encoding and length to the * OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string * @param cStringLength The length of the UTF-8 encoded C string */ - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength; /** * @brief Appends a formatted string to the OFMutableString. * * See `printf` for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A format string which generates the string to append */ - (void)appendFormat: (OFConstantString *)format, ...; /** * @brief Appends a formatted string to the OFMutableString. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A format string which generates the string to append * @param arguments The arguments used in the format string */ - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments; | > > > > > > > > > > > > < < < < < < < < < < < < | 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 | */ - (void)appendCharacters: (const OFUnichar *)characters length: (size_t)length; /** * @brief Appends a UTF-8 encoded C string to the OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append * @throw OFInvalidEncodingException The C string is not in not in the correct * encoding */ - (void)appendUTF8String: (const char *)UTF8String; /** * @brief Appends a UTF-8 encoded C string with the specified length to the * OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append * @param UTF8StringLength The length of the UTF-8 encoded C string * @throw OFInvalidEncodingException The C string is not in not in the correct * encoding */ - (void)appendUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; /** * @brief Appends a C string with the specified encoding to the OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string * @throw OFInvalidEncodingException The C string is not in not in the correct * encoding */ - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding; /** * @brief Appends a C string with the specified encoding and length to the * OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string * @param cStringLength The length of the UTF-8 encoded C string * @throw OFInvalidEncodingException The C string is not in not in the correct * encoding */ - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength; /** * @brief Appends a formatted string to the OFMutableString. * * See `printf` for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A format string which generates the string to append * @throw OFInvalidFormatException The specified format is invalid * @throw OFInvalidEncodingException The resulting string is not in not in UTF-8 * encoding */ - (void)appendFormat: (OFConstantString *)format, ...; /** * @brief Appends a formatted string to the OFMutableString. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A format string which generates the string to append * @param arguments The arguments used in the format string * @throw OFInvalidFormatException The specified format is invalid */ - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments; /** * @brief Converts the string to uppercase. */ - (void)uppercase; /** * @brief Converts the string to lowercase. |
︙ | ︙ |
Modified src/OFMutableString.m from [a015aada74] to [eb3bef8a08].
︙ | ︙ | |||
170 171 172 173 174 175 176 | { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path encoding: encoding]; } #endif | | | | | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path encoding: encoding]; } #endif - (instancetype)initWithContentsOfURI: (OFURI *)URI { return (id)[[OFMutableUTF8String alloc] initWithContentsOfURI: URI]; } - (instancetype)initWithContentsOfURI: (OFURI *)URI encoding: (OFStringEncoding)encoding { return (id)[[OFMutableUTF8String alloc] initWithContentsOfURI: URI encoding: encoding]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMutableUTF8String alloc] initWithSerialization: element]; } |
︙ | ︙ | |||
285 286 287 288 289 290 291 | #endif - (void)setCharacter: (OFUnichar)character atIndex: (size_t)idx { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithCharacters: &character length: 1]; | | | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | #endif - (void)setCharacter: (OFUnichar)character atIndex: (size_t)idx { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithCharacters: &character length: 1]; [self replaceCharactersInRange: OFMakeRange(idx, 1) withString: string]; objc_autoreleasePoolPop(pool); } - (void)appendString: (OFString *)string { [self insertString: string atIndex: self.length]; } |
︙ | ︙ | |||
368 369 370 371 372 373 374 | @try { [self appendUTF8String: UTF8String length: UTF8StringLength]; } @finally { free(UTF8String); } } | < < < < < < < < < < < < < < < < | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | @try { [self appendUTF8String: UTF8String length: UTF8StringLength]; } @finally { free(UTF8String); } } #ifdef OF_HAVE_UNICODE_TABLES - (void)uppercase { [self of_convertWithWordStartTable: OFUnicodeUppercaseTable wordMiddleTable: OFUnicodeUppercaseTable wordStartTableSize: OFUnicodeUppercaseTableSize wordMiddleTableSize: OFUnicodeUppercaseTableSize]; |
︙ | ︙ | |||
427 428 429 430 431 432 433 | { convert(self, OFASCIIToUpper, OFASCIIToLower); } #endif - (void)insertString: (OFString *)string atIndex: (size_t)idx { | | | | 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 | { convert(self, OFASCIIToUpper, OFASCIIToLower); } #endif - (void)insertString: (OFString *)string atIndex: (size_t)idx { [self replaceCharactersInRange: OFMakeRange(idx, 0) withString: string]; } - (void)deleteCharactersInRange: (OFRange)range { [self replaceCharactersInRange: range withString: @""]; } - (void)replaceCharactersInRange: (OFRange)range withString: (OFString *)replacement { OF_UNRECOGNIZED_SELECTOR } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { [self replaceOccurrencesOfString: string withString: replacement options: 0 range: OFMakeRange(0, self.length)]; } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range { |
︙ | ︙ | |||
481 482 483 484 485 486 487 | characters = self.characters; for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(OFUnichar)) != 0) continue; | | | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | characters = self.characters; for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(OFUnichar)) != 0) continue; [self replaceCharactersInRange: OFMakeRange(i, searchLength) withString: replacement]; range.length -= searchLength; range.length += replacementLength; i += replacementLength - 1; |
︙ | ︙ | |||
513 514 515 516 517 518 519 | if (!OFASCIIIsSpace(c)) break; } objc_autoreleasePoolPop(pool); | | | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | if (!OFASCIIIsSpace(c)) break; } objc_autoreleasePoolPop(pool); [self deleteCharactersInRange: OFMakeRange(0, i)]; } - (void)deleteTrailingWhitespaces { void *pool; const OFUnichar *characters, *p; size_t length, d; |
︙ | ︙ | |||
540 541 542 543 544 545 546 | break; d++; } objc_autoreleasePoolPop(pool); | | | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | break; d++; } objc_autoreleasePoolPop(pool); [self deleteCharactersInRange: OFMakeRange(length - d, d)]; } - (void)deleteEnclosingWhitespaces { [self deleteLeadingWhitespaces]; [self deleteTrailingWhitespaces]; } |
︙ | ︙ |
Modified src/OFMutableTarArchiveEntry.h from [f3b4444a50] to [d5cbafa370].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | * 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 "OFTarArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFMutableTarArchiveEntry \ * OFMutableTarArchiveEntry.h ObjFW/OFMutableTarArchiveEntry.h * * @brief A class which represents a mutable entry of a tar archive. */ | > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > | 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 | * 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 "OFTarArchiveEntry.h" #import "OFMutableArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFMutableTarArchiveEntry \ * OFMutableTarArchiveEntry.h ObjFW/OFMutableTarArchiveEntry.h * * @brief A class which represents a mutable entry of a tar archive. */ @interface OFMutableTarArchiveEntry: OFTarArchiveEntry <OFMutableArchiveEntry> { OF_RESERVE_IVARS(OFMutableTarArchiveEntry, 4) } /** * @brief The type of the archive entry. * * See @ref OFTarArchiveEntryType. */ @property (readwrite, nonatomic) OFTarArchiveEntryType type; /** * @brief The file name of the target (for a hard link or symbolic link). */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *targetFileName; /** * @brief The device major (if the file is a device). */ @property (readwrite, nonatomic) unsigned long deviceMajor; /** * @brief The device major (if the file is a device). */ @property (readwrite, nonatomic) unsigned long deviceMinor; /** * @brief Creates a new OFMutableTarArchiveEntry with the specified file name. * * @param fileName The file name for the OFTarArchiveEntry * @return A new, autoreleased OFTarArchiveEntry */ + (instancetype)entryWithFileName: (OFString *)fileName; /** * @brief Initializes an already allocated OFMutableTarArchiveEntry with the * specified file name. * * @param fileName The file name for the OFTarArchiveEntry * @return An initialized OFTarArchiveEntry */ - (instancetype)initWithFileName: (OFString *)fileName; /** * @brief Converts the OFMutableTarArchiveEntry to an immutable * OFTarArchiveEntry. */ - (void)makeImmutable; @end |
︙ | ︙ |
Modified src/OFMutableTarArchiveEntry.m from [bfb188d370] to [693af0fda5].
︙ | ︙ | |||
12 13 14 15 16 17 18 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFMutableTarArchiveEntry.h" | > | | > > > > > > > > > | | > > > > > > > > > > > > > > > > > > | | > > | > > > > | > > > > > | | | | | 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 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFMutableTarArchiveEntry.h" #import "OFTarArchiveEntry+Private.h" #import "OFDate.h" #import "OFNumber.h" #import "OFString.h" @implementation OFMutableTarArchiveEntry @dynamic fileName, POSIXPermissions, ownerAccountID, groupOwnerAccountID; @dynamic compressedSize, uncompressedSize, modificationDate, type; @dynamic targetFileName, ownerAccountName, groupOwnerAccountName, deviceMajor; @dynamic deviceMinor; /* * The following is optional in OFMutableArchiveEntry, but Apple GCC 4.0.1 is * buggy and needs this to stop complaining. */ @dynamic fileComment; + (instancetype)entryWithFileName: (OFString *)fileName { return [[[self alloc] initWithFileName: fileName] autorelease]; } - (instancetype)initWithFileName: (OFString *)fileName { self = [super of_init]; @try { _fileName = [fileName copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (id)copy { OFMutableTarArchiveEntry *copy = [self mutableCopy]; [copy makeImmutable]; return copy; } - (void)setFileName: (OFString *)fileName { OFString *old = _fileName; _fileName = [fileName copy]; [old release]; } - (void)setPOSIXPermissions: (OFNumber *)POSIXPermissions { OFNumber *old = _POSIXPermissions; _POSIXPermissions = [POSIXPermissions retain]; [old release]; } - (void)setOwnerAccountID: (OFNumber *)ownerAccountID { OFNumber *old = _ownerAccountID; _ownerAccountID = [ownerAccountID retain]; [old release]; } - (void)setGroupOwnerAccountID: (OFNumber *)groupOwnerAccountID { OFNumber *old = _groupOwnerAccountID; _groupOwnerAccountID = [groupOwnerAccountID retain]; [old release]; } - (void)setCompressedSize: (unsigned long long)compressedSize { _compressedSize = compressedSize; } - (void)setUncompressedSize: (unsigned long long)uncompressedSize { _uncompressedSize = uncompressedSize; } - (void)setModificationDate: (OFDate *)modificationDate { OFDate *old = _modificationDate; _modificationDate = [modificationDate retain]; [old release]; |
︙ | ︙ | |||
74 75 76 77 78 79 80 | - (void)setTargetFileName: (OFString *)targetFileName { OFString *old = _targetFileName; _targetFileName = [targetFileName copy]; [old release]; } | | | | | | | | 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 | - (void)setTargetFileName: (OFString *)targetFileName { OFString *old = _targetFileName; _targetFileName = [targetFileName copy]; [old release]; } - (void)setOwnerAccountName: (OFString *)ownerAccountName { OFString *old = _ownerAccountName; _ownerAccountName = [ownerAccountName copy]; [old release]; } - (void)setGroupOwnerAccountName: (OFString *)groupOwnerAccountName { OFString *old = _groupOwnerAccountName; _groupOwnerAccountName = [groupOwnerAccountName copy]; [old release]; } - (void)setDeviceMajor: (unsigned long)deviceMajor { _deviceMajor = deviceMajor; } |
︙ | ︙ |