Index: .fossil-settings/clean-glob
==================================================================
--- .fossil-settings/clean-glob
+++ .fossil-settings/clean-glob
@@ -30,21 +30,27 @@
src/bridge/Info.plist
src/libobjfw.*
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/libobjfwrt.*
+src/tls/Info.plist
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/objc_sync/objc_sync
tests/plugin/Info.plist
+tests/serialization_xml.m
tests/terminal/terminal_tests
+tests/testfile_bin.m
+tests/testfile_ini.m
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
Index: .fossil-settings/ignore-glob
==================================================================
--- .fossil-settings/ignore-glob
+++ .fossil-settings/ignore-glob
@@ -32,24 +32,30 @@
src/bridge/Info.plist
src/libobjfw.*
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/libobjfwrt.*
+src/tls/Info.plist
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser
tests/iOS.xcodeproj/project.xcworkspace
tests/iOS.xcodeproj/xcuserdata
tests/objc_sync/objc_sync
tests/plugin/Info.plist
+tests/serialization_xml.m
tests/terminal/terminal_tests
+tests/testfile_bin.m
+tests/testfile_ini.m
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
Index: .github/workflows/amiga-gcc.yml
==================================================================
--- .github/workflows/amiga-gcc.yml
+++ .github/workflows/amiga-gcc.yml
@@ -1,9 +1,9 @@
name: amiga-gcc
on: [push, pull_request]
jobs:
- tests:
+ build:
runs-on: ubuntu-latest
strategy:
matrix:
configure_flags:
-
Index: .github/workflows/ios.yml
==================================================================
--- .github/workflows/ios.yml
+++ .github/workflows/ios.yml
@@ -1,9 +1,9 @@
name: ios
on: [push, pull_request]
jobs:
- tests:
+ build:
runs-on: macos-latest
strategy:
matrix:
arch:
- arm64
ADDED .github/workflows/morphos.yml
Index: .github/workflows/morphos.yml
==================================================================
--- .github/workflows/morphos.yml
+++ .github/workflows/morphos.yml
@@ -0,0 +1,37 @@
+name: morphos
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --disable-amiga-lib
+ steps:
+ - name: Install dependencies
+ run: docker pull amigadev/crosstools:ppc-morphos
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e PATH="/opt/ppc-morphos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:ppc-morphos \
+ sh -c 'cd /objfw && ./configure --host=ppc-morphos ${{ matrix.configure_flags }}'
+ - name: make
+ run: |
+ docker run \
+ -e PATH="/opt/ppc-morphos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:ppc-morphos \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e PATH="/opt/ppc-morphos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:ppc-morphos \
+ sh -c "cd /objfw && make -j$(nproc)"
Index: .github/workflows/nintendo-3ds.yml
==================================================================
--- .github/workflows/nintendo-3ds.yml
+++ .github/workflows/nintendo-3ds.yml
@@ -1,9 +1,9 @@
name: nintendo-3ds
on: [push, pull_request]
jobs:
- tests:
+ build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitarm
- uses: actions/checkout@v2
Index: .github/workflows/nintendo-ds.yml
==================================================================
--- .github/workflows/nintendo-ds.yml
+++ .github/workflows/nintendo-ds.yml
@@ -1,9 +1,9 @@
name: nintendo-ds
on: [push, pull_request]
jobs:
- tests:
+ build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitarm
- uses: actions/checkout@v2
ADDED .github/workflows/nintendo-switch.yml
Index: .github/workflows/nintendo-switch.yml
==================================================================
--- .github/workflows/nintendo-switch.yml
+++ .github/workflows/nintendo-switch.yml
@@ -0,0 +1,35 @@
+name: nintendo-switch
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkita64
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkita64 \
+ sh -c 'cd /objfw && ./configure --host=aarch64-none-elf --with-nintendo-switch'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkita64 \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - 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 -j$(nproc)"
Index: .github/workflows/ubuntu-18.04-32bit.yml
==================================================================
--- .github/workflows/ubuntu-18.04-32bit.yml
+++ .github/workflows/ubuntu-18.04-32bit.yml
@@ -4,26 +4,28 @@
tests:
runs-on: ubuntu-18.04
strategy:
matrix:
configure_flags:
- -
- - --enable-seluid24
- - --disable-compiler-tls
- - --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
- - --disable-shared --enable-seluid24
- - --disable-compiler-tls --disable-threads
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
steps:
- name: Install dependencies
- run: sudo apt install gcc-multilib
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-18.04-gcc-32bit.yml
==================================================================
--- .github/workflows/ubuntu-18.04-gcc-32bit.yml
+++ .github/workflows/ubuntu-18.04-gcc-32bit.yml
@@ -4,26 +4,28 @@
tests:
runs-on: ubuntu-18.04
strategy:
matrix:
configure_flags:
- -
- - --enable-seluid24
- - --disable-compiler-tls
- - --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
- - --disable-shared --enable-seluid24
- - --disable-compiler-tls --disable-threads
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
steps:
- name: Install dependencies
- run: sudo apt install gcc-multilib gobjc
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib gobjc
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc -m32" ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-18.04-gcc.yml
==================================================================
--- .github/workflows/ubuntu-18.04-gcc.yml
+++ .github/workflows/ubuntu-18.04-gcc.yml
@@ -17,13 +17,17 @@
- --disable-sockets --disable-files
- --disable-files
- --disable-shared
- --disable-shared --enable-seluid24
- --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
steps:
- name: Install dependencies
- run: sudo apt install gobjc
+ run: |
+ sudo apt-get update
+ sudo apt-get install gobjc libssl-dev gnutls-dev
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc" ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-18.04.yml
==================================================================
--- .github/workflows/ubuntu-18.04.yml
+++ .github/workflows/ubuntu-18.04.yml
@@ -17,11 +17,17 @@
- --disable-sockets --disable-files
- --disable-files
- --disable-shared
- --disable-shared --enable-seluid24
- --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install libssl-dev gnutls-dev
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-20.04-32bit.yml
==================================================================
--- .github/workflows/ubuntu-20.04-32bit.yml
+++ .github/workflows/ubuntu-20.04-32bit.yml
@@ -4,26 +4,28 @@
tests:
runs-on: ubuntu-20.04
strategy:
matrix:
configure_flags:
- -
- - --enable-seluid24
- - --disable-compiler-tls
- - --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
- - --disable-shared --enable-seluid24
- - --disable-compiler-tls --disable-threads
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
steps:
- name: Install dependencies
- run: sudo apt install gcc-multilib
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-20.04-gcc-32bit.yml
==================================================================
--- .github/workflows/ubuntu-20.04-gcc-32bit.yml
+++ .github/workflows/ubuntu-20.04-gcc-32bit.yml
@@ -4,26 +4,28 @@
tests:
runs-on: ubuntu-20.04
strategy:
matrix:
configure_flags:
- -
- - --enable-seluid24
- - --disable-compiler-tls
- - --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
- - --disable-shared --enable-seluid24
- - --disable-compiler-tls --disable-threads
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
steps:
- name: Install dependencies
- run: sudo apt install gcc-multilib gobjc
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib gobjc
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc -m32" ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-20.04-gcc.yml
==================================================================
--- .github/workflows/ubuntu-20.04-gcc.yml
+++ .github/workflows/ubuntu-20.04-gcc.yml
@@ -17,13 +17,17 @@
- --disable-sockets --disable-files
- --disable-files
- --disable-shared
- --disable-shared --enable-seluid24
- --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
steps:
- name: Install dependencies
- run: sudo apt install gobjc
+ run: |
+ sudo apt-get update
+ sudo apt-get install gobjc libssl-dev gnutls-dev
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc" ${{ matrix.configure_flags }}
Index: .github/workflows/ubuntu-20.04.yml
==================================================================
--- .github/workflows/ubuntu-20.04.yml
+++ .github/workflows/ubuntu-20.04.yml
@@ -17,11 +17,17 @@
- --disable-sockets --disable-files
- --disable-files
- --disable-shared
- --disable-shared --enable-seluid24
- --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install libssl-dev gnutls-dev
- uses: actions/checkout@v2
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure ${{ matrix.configure_flags }}
ADDED .github/workflows/wii-u.yml
Index: .github/workflows/wii-u.yml
==================================================================
--- .github/workflows/wii-u.yml
+++ .github/workflows/wii-u.yml
@@ -0,0 +1,35 @@
+name: wii-u
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkitppc
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c 'cd /objfw && ./configure --host=powerpc-eabi --with-wii-u'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - 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 -j$(nproc)"
Index: .github/workflows/wii.yml
==================================================================
--- .github/workflows/wii.yml
+++ .github/workflows/wii.yml
@@ -1,9 +1,9 @@
name: wii
on: [push, pull_request]
jobs:
- tests:
+ build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitppc
- uses: actions/checkout@v2
Index: .gitignore
==================================================================
--- .gitignore
+++ .gitignore
@@ -32,24 +32,30 @@
src/bridge/Info.plist
src/libobjfw.*
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/libobjfwrt.*
+src/tls/Info.plist
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser
tests/iOS.xcodeproj/project.xcworkspace
tests/iOS.xcodeproj/xcuserdata
tests/objc_sync/objc_sync
tests/plugin/Info.plist
+tests/serialization_xml.m
tests/terminal/terminal_tests
+tests/testfile_bin.m
+tests/testfile_ini.m
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
Index: Doxyfile
==================================================================
--- Doxyfile
+++ Doxyfile
@@ -1,15 +1,18 @@
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(...)= \
Index: PLATFORMS.md
==================================================================
--- PLATFORMS.md
+++ PLATFORMS.md
@@ -103,10 +103,20 @@
* OS Versions: 10.5, 10.7-10.15, Darling
* Architectures: PowerPC, PowerPC64, x86, x86_64
* Compilers: Clang 3.1-10.0, Apple GCC 4.0.1 & 4.2.1
* Runtimes: Apple, ObjFW
+
+MiNT
+----
+
+ * OS Versions: FreeMiNT 1.19
+ * Architectures: m68k
+ * Runtimes: ObjFW
+ * Compilers: GCC 4.6.4 (MiNT 20130415)
+ * Limitations: No shared libraries, no threads
+
MorphOS
-------
* OS Versions: 3.14
@@ -142,10 +152,20 @@
* Compilers: GCC 4.8.2 (devkitARM release 42)
* Runtimes: ObjFW
* Limitations: No threads, no sockets
* Notes: File support requires an argv-compatible launcher (such as HBMenu)
+
+Nintendo Switch
+---------------
+
+ * OS Versions: yuzu 1093
+ * Architectures: AArch64
+ * Compilers: GCC 12.1.0 (devkitA64 release 19)
+ * Runtimes: ObjFW
+ * Limitations: No sockets, no shared libraries, not tested on real hardware
+
OpenBSD
-------
* OS Versions: 5.2-6.7
@@ -189,20 +209,32 @@
* Architectures: PowerPC
* Compilers: GCC 4.6.3 (devkitPPC release 26)
* Runtimes: ObjFW
* Limitations: No threads
+
+Wii U
+-----
+
+ * OS Versions: Cemu 12.26.2f
+ * Architectures: PowerPC
+ * Compilers: gcc version 12.1.0 (devkitPPC release 41)
+ * Runtimes: ObjFW
+ * Limitations: No files, no threads, no sockets, no shared libraries, not
+ tested on real hardware
+
Windows
-------
- * OS Versions: 98 SE, NT 4.0, XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10,
+ * OS Versions: 98 SE, NT 4.0, XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10, 11,
Wine (x86 & x64)
- * Architectures: x86, x86_64
+ * Architectures: x86, x86_64, AArch64
* Compilers: GCC 5.3.0 & 6.2.0 from msys2 (x86 & x64),
Clang 3.9.0 from msys2 (x86),
- Clang 10.0 from msys2 (x86 & x86_64)
+ Clang 10.0 from msys2 (x86 & x86_64),
+ Clang 14.0.4 from msys2 (AArch64)
* Runtimes: ObjFW
Others
------
Index: README.md
==================================================================
--- README.md
+++ README.md
@@ -30,10 +30,12 @@
* [Amiga](#amiga)
* [Writing your first application with ObjFW](#first-app)
* [Documentation](#documentation)
* [Bugs and feature requests](#bugs)
* [Support and community](#support)
+ * [Donating](#donating)
+ * [Thanks](#thanks)
* [Commercial use](#commercial-use)
What is ObjFW?
@@ -122,10 +124,16 @@
In order to verify the signature of the currently checked out checkin, you
can use:
$ fossil artifact current | gpg --verify
+ Please note that not all checkins are signed, as the signing key only resides
+ on trusted systems. This means that checkins I perform on e.g. Windows are
+ unsigned. However, usually it should not take long until there is another
+ signed checkin. Alternatively, you can go back until the last signed checkin
+ and review changes from there on.
+
Git
To clone the Git repository, use the following:
$ git clone https://github.com/ObjFW/ObjFW
@@ -137,11 +145,12 @@
To install ObjFW, just run the following commands:
$ ./configure
$ make
- $ make install
+ $ make check
+ $ sudo make install
In case you checked out ObjFW from the Fossil or Git repository, you need to
run the following command first:
$ ./autogen.sh
@@ -149,27 +158,33 @@
macOS and iOS
Building as a framework
When building for macOS or iOS, everything is built as a `.framework` by
- default if `--disable-shared` has not been specified to `configure`.
+ default if `--disable-shared` has not been specified to `./configure`. The
+ frameworks will end up in `$PREFIX/Library/Frameworks`.
- To build for iOS, use something like this:
+ To build for macOS, just follow the
+ regular instructions above.
+
+ To build for iOS, follow the regular instructions, but instead of
+ `./configure` do something like this:
$ clang="clang -isysroot $(xcrun --sdk iphoneos --show-sdk-path)"
$ export OBJC="$clang -arch armv7 -arch arm64"
$ export OBJCPP="$clang -arch armv7 -E"
$ export IPHONEOS_DEPLOYMENT_TARGET="9.0"
$ ./configure --prefix=/usr/local/ios --host=arm64-apple-darwin
- To build for the iOS simulator, use something like this:
+ To build for the iOS simulator, follow the regular instructions, but instead
+ of `./configure` use something like this:
$ clang="clang -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path)"
- $ export OBJC="$clang -arch i386 -arch x86_64"
- $ export OBJCPP="$clang -arch i386 -E"
+ $ export OBJC="$clang -arch arm64 -arch x86_64"
+ $ export OBJCPP="$clang -arch arm64 -E"
$ export IPHONEOS_DEPLOYMENT_TARGET="9.0"
- $ ./configure --prefix=/usr/local/iossim --host=x86_64-apple-darwin
+ $ ./configure --prefix=/usr/local/iossim --host=arm64-apple-darwin
Using the macOS or iOS framework in Xcode
To use the macOS framework in Xcode, you need to add the `.framework`s to
your project and add the following flags to `Other C Flags`:
@@ -354,12 +369,27 @@
* A [Gitter room](https://gitter.im/ObjFW/ObjFW), bridged to the Matrix room
above
Please don't hesitate to join any or all of those!
+
+Donating
+
+ If you want to donate to ObjFW, you can read about possible ways to do so
+ [here](https://objfw.nil.im/wiki?name=Donating).
+
+
+Thanks
+
+ * Thank you to [Jonathan Neuschäfer](https://github.com/neuschaefer) for
+ reviewing the *entirety* (all 84k LoC at the time) of ObjFW's codebase in
+ 2017!
+ * Thank you to [Hill Ma](https://github.com/mahiuchun) for donating an M1 Mac
+ Mini to the project!
+
Commercial use
If for whatever reason neither the terms of the QPL nor those of the GPL work
for you, a proprietary license for ObjFW including support is available upon
request. Just write a mail to js@nil.im and we can find a reasonable solution
for both parties.
Index: build-aux/m4/buildsys.m4
==================================================================
--- build-aux/m4/buildsys.m4
+++ build-aux/m4/buildsys.m4
@@ -20,17 +20,17 @@
dnl CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
dnl ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
dnl POSSIBILITY OF SUCH DAMAGE.
dnl
-AC_ARG_ENABLE(rpath,
- AS_HELP_STRING([--disable-rpath], [do not use rpath]))
-
AC_DEFUN([BUILDSYS_INIT], [
AC_REQUIRE([AC_CANONICAL_BUILD])
AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_ARG_ENABLE(rpath,
+ AS_HELP_STRING([--disable-rpath], [do not use rpath]))
+
case "$build_os" in
darwin*)
case "$host_os" in
darwin*)
AC_SUBST(BUILD_AND_HOST_ARE_DARWIN, yes)
@@ -203,20 +203,21 @@
CLEAN_LIB=''
;;
*-*-mingw* | *-*-cygwin*)
AC_MSG_RESULT(MinGW / Cygwin)
LIB_CFLAGS=''
- LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,lib$${out%${LIB_SUFFIX}}.a'
+ LIB_LDFLAGS='-shared -Wl,--export-all-symbols'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX=''
LIB_SUFFIX='${LIB_MAJOR}.dll'
+ LINK_LIB='&& ${LN_S} $$out lib$${out%${LIB_SUFFIX}}.dll.a'
PLUGIN_CFLAGS=''
- PLUGIN_LDFLAGS='-shared'
+ 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}}.a ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.a'
- UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$$i.a'
+ 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'
UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB='${SHARED_LIB}.a ${SHARED_LIB_NOINST}.a'
;;
*-*-openbsd* | *-*-mirbsd*)
ADDED build-aux/m4/pkg.m4
Index: build-aux/m4/pkg.m4
==================================================================
--- build-aux/m4/pkg.m4
+++ build-aux/m4/pkg.m4
@@ -0,0 +1,343 @@
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+# serial 11 (pkg-config-0.29.1)
+
+dnl Copyright © 2004 Scott James Remnant .
+dnl Copyright © 2012-2015 Dan Nicholson
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see .])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
+dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
+dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
+dnl [DESCRIPTION], [DEFAULT])
+dnl ------------------------------------------
+dnl
+dnl Prepare a "--with-" configure option using the lowercase
+dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
+dnl PKG_CHECK_MODULES in a single macro.
+AC_DEFUN([PKG_WITH_MODULES],
+[
+m4_pushdef([with_arg], m4_tolower([$1]))
+
+m4_pushdef([description],
+ [m4_default([$5], [build with ]with_arg[ support])])
+
+m4_pushdef([def_arg], [m4_default([$6], [auto])])
+m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
+m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
+
+m4_case(def_arg,
+ [yes],[m4_pushdef([with_without], [--without-]with_arg)],
+ [m4_pushdef([with_without],[--with-]with_arg)])
+
+AC_ARG_WITH(with_arg,
+ AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
+ [AS_TR_SH([with_]with_arg)=def_arg])
+
+AS_CASE([$AS_TR_SH([with_]with_arg)],
+ [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
+ [auto],[PKG_CHECK_MODULES([$1],[$2],
+ [m4_n([def_action_if_found]) $3],
+ [m4_n([def_action_if_not_found]) $4])])
+
+m4_popdef([with_arg])
+m4_popdef([description])
+m4_popdef([def_arg])
+
+])dnl PKG_WITH_MODULES
+
+dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
+dnl [DESCRIPTION], [DEFAULT])
+dnl -----------------------------------------------
+dnl
+dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
+dnl check._[VARIABLE-PREFIX] is exported as make variable.
+AC_DEFUN([PKG_HAVE_WITH_MODULES],
+[
+PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
+
+AM_CONDITIONAL([HAVE_][$1],
+ [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
+])dnl PKG_HAVE_WITH_MODULES
+
+dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
+dnl [DESCRIPTION], [DEFAULT])
+dnl ------------------------------------------------------
+dnl
+dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
+dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
+dnl and preprocessor variable.
+AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
+[
+PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
+
+AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
+ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
+])dnl PKG_HAVE_DEFINE_WITH_MODULES
Index: configure.ac
==================================================================
--- configure.ac
+++ configure.ac
@@ -44,10 +44,11 @@
LDFLAGS="$LDFLAGS -noixemul"
LIBS="$LIBS -ldebug"
enable_files="yes" # Required for reading ENV:
enable_shared="no"
+ with_tls="no"
supports_amiga_lib="yes"
AS_IF([test x"$enable_amiga_lib" != x"no"], [
AC_SUBST(OBJFW_AMIGA_LIB, 'objfw${OBJFW_LIB_MAJOR}.library')
AC_SUBST(OBJFWRT_AMIGA_LIB,
@@ -65,10 +66,11 @@
powerpc-*-amigaos*)
CPPFLAGS="$CPPFLAGS -D__USE_INLINE__"
enable_files="yes" # Required for reading ENV:
enable_shared="no"
+ with_tls="no"
AC_SUBST(LIBBASES_M, libbases.m)
;;
*-morphos*)
AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O2 -g"])
@@ -139,10 +141,15 @@
dnl also used for .S files.
OBJCFLAGS="$OBJCFLAGS -include inttypes.h"
dnl We need -latomic for GCC's atomics to work.
LIBS="$LIBS -latomic"
;;
+*-*-mint*)
+ enable_shared="no"
+ enable_threads="no" # TODO
+ with_tls="no"
+ ;;
esac
AS_IF([test x"$host_os" = x"msdosdjgpp" -a x"$build_os" = x"msdosdjgpp"], [
dnl Hack to make configure find these on DOS.
: ${AR:=ar.exe}
@@ -177,18 +184,43 @@
flags="-mrvl -mcpu=750 -meabi -mhard-float"
OBJCFLAGS="$OBJCFLAGS $flags"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
CPPFLAGS="$CPPFLAGS -DGEKKO -I$DEVKITPRO/libogc/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DGEKKO -I\$DEVKITPRO/libogc/include"
LDFLAGS="$LDFLAGS -mrvl -mcpu=750 -meabi -mhard-float"
LIBS="$LIBS -L$DEVKITPRO/libogc/lib/wii -lfat -logc"
TESTS_LIBS="$TESTS_LIBS -lwiiuse -lbte"
enable_shared="no"
enable_threads="no" # TODO
+ with_tls="no"
AC_DEFINE(OF_WII, 1, [Whether we are compiling for Wii])
- OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DGEKKO -I\$DEVKITPRO/libogc/include"
+ AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
+])
+
+AC_ARG_WITH(wii-u,
+ AS_HELP_STRING([--with-wii-u], [build for Wii U]))
+AS_IF([test x"$with_wii_u" = x"yes"], [
+ AS_IF([test x"$DEVKITPRO" = x""], [
+ AC_MSG_ERROR([DEVKITPRO is not set! Please set DEVKITPRO.])
+ ])
+
+ flags="-mcpu=750 -meabi -mhard-float"
+ OBJCFLAGS="$OBJCFLAGS $flags"
+ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
+ CPPFLAGS="-isystem $DEVKITPRO/wut/include -D__WIIU__ -D__WUT__"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -isystem \$DEVKITPRO/wut/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -D__WIIU__ -D__WUT__"
+ LDFLAGS="-specs=$DEVKITPRO/wut/share/wut.specs"
+ LIBS="-L$DEVKITPRO/wut/lib -L$DEVKITPRO/wut/lib/stubs -lwut"
+ enable_files="no" # TODO
+ enable_shared="no" # TODO
+ enable_threads="no" # TODO
+ enable_sockets="no" # TODO
+
+ AC_DEFINE(OF_WII_U, 1, [Whether we are compiling for Wii U])
AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
])
AC_ARG_WITH(nds,
AS_HELP_STRING([--with-nds], [build for Nintendo DS]))
@@ -199,20 +231,20 @@
flags="-march=armv5te -mtune=arm946e-s -mthumb -mthumb-interwork"
OBJCFLAGS="$OBJCFLAGS $flags"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
CPPFLAGS="$CPPFLAGS -DARM9 -I$DEVKITPRO/libnds/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM9 -I\$DEVKITPRO/libnds/include"
ASFLAGS="$ASFLAGS -march=armv5te"
LDFLAGS="$LDFLAGS -specs=ds_arm9.specs"
LIBS="$LIBS -L$DEVKITPRO/libnds/lib -lfilesystem -lfat -lnds9"
enable_shared="no"
enable_threads="no" # TODO
enable_sockets="no" # TODO
check_pedantic="no"
AC_DEFINE(OF_NINTENDO_DS, 1, [Whether we are compiling for Nintendo DS])
- OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM9 -I\$DEVKITPRO/libnds/include"
AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
])
AC_ARG_WITH(3ds,
AS_HELP_STRING([--with-3ds], [build for Nintendo 3DS]))
@@ -224,23 +256,48 @@
flags="-march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft"
flags="$flags -mword-relocations"
OBJCFLAGS="$OBJCFLAGS $flags"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
CPPFLAGS="$CPPFLAGS -DARM11 -I$DEVKITPRO/libctru/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM11 -I\$DEVKITPRO/libctru/include"
ASFLAGS="$ASFLAGS -march=armv6k"
LDFLAGS="$LDFLAGS -specs=3dsx.specs -march=armv6k -mtune=mpcore"
LDFLAGS="$LDFLAGS -mfloat-abi=hard -mtp=soft -mword-relocations"
LIBS="$LIBS -L$DEVKITPRO/libctru/lib -lctru"
enable_shared="no"
enable_threads="no" # TODO
+ with_tls="no"
check_pedantic="no"
AC_DEFINE(OF_NINTENDO_3DS, 1,
[Whether we are compiling for Nintendo 3DS])
- OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM11 -I\$DEVKITPRO/libctru/include"
AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
])
+
+AC_ARG_WITH(nintendo-switch,
+ AS_HELP_STRING([--with-nintendo-switch], [build for Nintendo Switch]))
+AS_IF([test x"$with_nintendo_switch" = x"yes"], [
+ AS_IF([test x"$DEVKITPRO" = x""], [
+ AC_MSG_ERROR([DEVKITPRO is not set! Please set DEVKITPRO.])
+ ])
+
+ flags="-march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE"
+ OBJCFLAGS="$OBJCFLAGS $flags"
+ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
+ CPPFLAGS="$CPPFLAGS -D__SWITCH__ -I$DEVKITPRO/libnx/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -D__SWITCH__ -I$DEVKITPRO/libnx/include"
+ ASFLAGS="$ASFLAGS $flags"
+ LDFLAGS="$LDFLAGS -specs=$DEVKITPRO/libnx/switch.specs $flags"
+ LIBS="$LIBS -L$DEVKITPRO/libnx/lib -lnx"
+ enable_shared="no"
+ enable_threads="yes"
+ enable_sockets="no" # TODO
+ check_pedantic="no"
+
+ AC_DEFINE(OF_NINTENDO_SWITCH, 1,
+ [Whether we are compiling for Nintendo Switch])
+])
CPP="$OBJCPP"
CPPFLAGS="$CPPFLAGS $OBJCPPFLAGS -DOF_COMPILING_OBJFW"
flags="-fexceptions -fobjc-exceptions -funwind-tables"
flags="$flags -fconstant-string-class=OFConstantString"
@@ -434,11 +491,11 @@
AC_MSG_CHECKING(whether we need -D_GNU_SOURCE)
AC_EGREP_CPP(egrep_cpp_yes, [
#include
#if defined(__GLIBC__) || defined(__MINGW32__) || \
- defined(__NEWLIB__) || defined(__MORPHOS__)
+ defined(__NEWLIB__) || defined(__MORPHOS__) || defined(__MINT__)
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS"
@@ -648,10 +705,13 @@
OBJCFLAGS="$old_OBJCFLAGS"
;;
esac
case "$host_os" in
+mint*)
+ dnl _Unwind_Backtrace crashes on MiNT
+ ;;
hpux*)
dnl _Unwind_Backtrace() returns complete garbage on HP-UX.
;;
*)
AC_CHECK_FUNCS(_Unwind_Backtrace)
@@ -837,10 +897,14 @@
AC_CHECK_FUNCS(strtof truncf)
AC_CHECK_FUNC(asprintf, [
case "$host" in
+ *-*-mint*)
+ dnl asprintf is not in headers
+ have_asprintf="no"
+ ;;
*-*-mingw*)
dnl asprintf from MinGW is broken on older Windows versions
have_asprintf="no"
;;
*-psp-*)
@@ -1351,10 +1415,13 @@
AC_CHECK_HEADER(netinet/tcp.h, [
AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1,
[Whether we have netinet/tcp.h])
])
AC_CHECK_HEADERS([arpa/inet.h netdb.h])
+ AC_CHECK_HEADER(sys/un.h, [
+ AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
+ ])
AC_CHECK_HEADER(netipx/ipx.h, [
AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1,
[Whether we have netipx/ipx.h])
])
@@ -1407,10 +1474,44 @@
# endif
# include
# include
#endif
])
+
+ AC_CHECK_HEADERS(afunix.h, [
+ AC_DEFINE(OF_HAVE_AFUNIX_H, 1, [Whether we have afunix.h])
+ ], [], [
+ #ifdef _WIN32
+ # include
+ #endif
+ ])
+ AC_CHECK_MEMBER(struct sockaddr_un.sun_path, [
+ AC_DEFINE(OF_HAVE_UNIX_SOCKETS, 1,
+ [Whether we have UNIX sockets])
+ AC_SUBST(USE_SRCS_UNIX_SOCKETS, '${SRCS_UNIX_SOCKETS}')
+ ], [], [
+ #ifdef OF_HAVE_SYS_TYPES_H
+ # include
+ #endif
+ #ifdef OF_HAVE_SYS_UN_H
+ # include
+ #endif
+ #ifdef _WIN32
+ # include
+ #endif
+ #ifdef HAVE_AFUNIX_H
+ # include
+ #endif
+
+ #ifdef __morphos__
+ # error MorphOS has the struct but does not support it
+ #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;
@@ -1524,18 +1625,124 @@
AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M,
"OFSelectKernelEventObserver.m")
])
;;
esac
+
+ AC_ARG_WITH(tls,
+ AS_HELP_STRING([--with-tls], [
+ enable TLS support using the specified library
+ (yes, openssl, gnutls, securetransport or no)]))
+ AS_IF([test x"$with_tls" = x""], [with_tls="yes"])
+ tls_support="no"
+
+ AS_IF([test x"$with_tls" = x"securetransport" \
+ -o x"$with_tls" = x"yes"], [
+ AC_CHECK_HEADERS(Security/SecureTransport.h, [
+ old_LIBS="$LIBS"
+ LIBS="-framework Security -framework Foundation $LIBS"
+
+ AC_CHECK_FUNC(SSLHandshake, [
+ AC_DEFINE(HAVE_SECURE_TRANSPORT, 1,
+ [Whether we have Secure Transport])
+
+ tls_support="Secure Transport"
+ TLS_LIBS="-framework Foundation $TLS_LIBS"
+ TLS_LIBS="-framework Security $TLS_LIBS"
+
+ AC_SUBST(OF_SECURE_TRANSPORT_TLS_STREAM_M,
+ "OFSecureTransportTLSStream.m")
+
+ 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"
+ ;;
+ *)
+ ssl="ssl"
+ crypto="crypto"
+ ;;
+ esac
+
+ AC_CHECK_LIB($ssl, SSL_set1_host, [
+ AC_CHECK_HEADER(openssl/ssl.h, [
+ AC_DEFINE(HAVE_OPENSSL, 1,
+ [Whether we have OpenSSL])
+
+ tls_support="OpenSSL"
+ TLS_LIBS="-l$ssl -l$crypto $TLS_LIBS"
+
+ AC_SUBST(OF_OPENSSL_TLS_STREAM_M,
+ "OFOpenSSLTLSStream.m")
+ ])
+ ], [], [-l$crypto])
+ ])
+
+ 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"$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)
+
+ OFHTTP_LIBS="-lobjfwtls $TLS_LIBS $OFHTTP_LIBS"
+
+ AS_IF([test x"$enable_shared" != x"no"], [
+ AC_SUBST(OBJFWTLS_SHARED_LIB,
+ "${LIB_PREFIX}objfwtls${LIB_SUFFIX}")
+ ])
+ AS_IF([test x"$enable_static" = x"yes" \
+ -o x"$enable_shared" = x"no"], [
+ AC_SUBST(OBJFWTLS_STATIC_LIB, "libobjfwtls.a")
+ ])
+ AS_IF([test x"$build_framework" = x"yes"], [
+ AC_SUBST(OBJFWTLS_FRAMEWORK, "ObjFWTLS.framework")
+ ])
+ ])
+
+ AS_IF([test x"$with_tls" != x"no" -a x"$tls_support" = x"no"], [
+ AC_MSG_ERROR(m4_normalize([
+ No TLS implementation was found. Please install OpenSSL,
+ GnuTLS or use --without-tls.
+ ]))
+ ])
AS_IF([test x"$enable_threads" != x"no"], [
AC_SUBST(OF_HTTP_CLIENT_TESTS_M, "OFHTTPClientTests.m")
])
AC_SUBST(OFDNS, "ofdns")
AS_IF([test x"$enable_files" != x"no"], [
AC_SUBST(OFHTTP, "ofhttp")
+ AC_SUBST(OFHTTP_LIBS)
])
])
AC_DEFUN([CHECK_BUILTIN_BSWAP], [
AC_MSG_CHECKING(for __builtin_bswap$1)
@@ -1571,10 +1778,13 @@
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
have_subprocesses="yes"
+
+ AC_CHECK_FUNCS(posix_spawnp)
+ AC_CHECK_HEADERS(spawn.h)
], [
AC_MSG_RESULT(no)
have_subprocesses="no"
])
;;
Index: extra.mk.in
==================================================================
--- extra.mk.in
+++ extra.mk.in
@@ -16,10 +16,14 @@
OBJFWBRIDGE_SHARED_LIB = @OBJFWBRIDGE_SHARED_LIB@
OBJFWBRIDGE_STATIC_LIB = @OBJFWBRIDGE_STATIC_LIB@
OBJFWBRIDGE_FRAMEWORK = @OBJFWBRIDGE_FRAMEWORK@
+OBJFWTLS_SHARED_LIB = @OBJFWTLS_SHARED_LIB@
+OBJFWTLS_STATIC_LIB = @OBJFWTLS_STATIC_LIB@
+OBJFWTLS_FRAMEWORK = @OBJFWTLS_FRAMEWORK@
+
BIN_PREFIX = @BIN_PREFIX@
BRIDGE = @BRIDGE@
CVINCLUDE_INLINE_H = @CVINCLUDE_INLINE_H@
ENCODINGS_A = @ENCODINGS_A@
ENCODINGS_AMIGALIB_A = @ENCODINGS_AMIGALIB_A@
@@ -46,15 +50,19 @@
OBJFW_LIBS = @OBJFW_LIBS@
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@
+OF_GNUTLS_TLS_STREAM_M = @OF_GNUTLS_TLS_STREAM_M@
OF_HTTP_CLIENT_TESTS_M = @OF_HTTP_CLIENT_TESTS_M@
OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@
+OF_OPENSSL_TLS_STREAM_M = @OF_OPENSSL_TLS_STREAM_M@
OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@
+OF_SECURE_TRANSPORT_TLS_STREAM_M = @OF_SECURE_TRANSPORT_TLS_STREAM_M@
OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@
OF_SUBPROCESS_M = @OF_SUBPROCESS_M@
REEXPORT_RUNTIME = @REEXPORT_RUNTIME@
REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@
RUNTIME = @RUNTIME@
@@ -68,14 +76,18 @@
SFD_FILE = @SFD_FILE@
TESTPLUGIN = @TESTPLUGIN@
TESTPLUGIN_LIBS = @TESTPLUGIN_LIBS@
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@
Index: generators/library/FuncArrayGenerator.h
==================================================================
--- generators/library/FuncArrayGenerator.h
+++ generators/library/FuncArrayGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/library/FuncArrayGenerator.m
==================================================================
--- generators/library/FuncArrayGenerator.m
+++ generators/library/FuncArrayGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/library/GlueGenerator.h
==================================================================
--- generators/library/GlueGenerator.h
+++ generators/library/GlueGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/library/GlueGenerator.m
==================================================================
--- generators/library/GlueGenerator.m
+++ generators/library/GlueGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/library/LibraryGenerator.m
==================================================================
--- generators/library/LibraryGenerator.m
+++ generators/library/LibraryGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -44,15 +44,23 @@
OFURL *glueURL = [sourcesURL
URLByAppendingPathComponent: @"amiga-glue.m"];
OFURL *funcArrayURL = [sourcesURL
URLByAppendingPathComponent: @"amiga-funcarray.inc"];
OFXMLElement *library = [OFXMLElement elementWithStream:
- [OFFile fileWithURL: libraryURL mode: @"r"]];
- OFFile *linkLib = [OFFile fileWithURL: linkLibURL mode: @"w"];
- OFFile *glueHeader = [OFFile fileWithURL: glueHeaderURL mode: @"w"];
- OFFile *glue = [OFFile fileWithURL: glueURL mode: @"w"];
- OFFile *funcArray = [OFFile fileWithURL: funcArrayURL mode: @"w"];
+ [OFFile fileWithPath: libraryURL.fileSystemRepresentation
+ mode: @"r"]];
+ OFFile *linkLib =
+ [OFFile fileWithPath: linkLibURL.fileSystemRepresentation
+ mode: @"w"];
+ OFFile *glueHeader =
+ [OFFile fileWithPath: glueHeaderURL.fileSystemRepresentation
+ mode: @"w"];
+ OFFile *glue =
+ [OFFile fileWithPath: glueURL.fileSystemRepresentation mode: @"w"];
+ OFFile *funcArray =
+ [OFFile fileWithPath: funcArrayURL.fileSystemRepresentation
+ mode: @"w"];
LinkLibGenerator *linkLibGenerator = [[[LinkLibGenerator alloc]
initWithLibrary: library
implementation: linkLib] autorelease];
GlueGenerator *glueGenerator = [[[GlueGenerator alloc]
initWithLibrary: library
Index: generators/library/LinkLibGenerator.h
==================================================================
--- generators/library/LinkLibGenerator.h
+++ generators/library/LinkLibGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/library/LinkLibGenerator.m
==================================================================
--- generators/library/LinkLibGenerator.m
+++ generators/library/LinkLibGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/library/copyright.h
==================================================================
--- generators/library/copyright.h
+++ generators/library/copyright.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -15,11 +15,11 @@
#import "OFString.h"
#define COPYRIGHT \
@"/*\n" \
- @" * Copyright (c) 2008-2021 Jonathan Schleifer \n" \
+ @" * Copyright (c) 2008-2022 Jonathan Schleifer \n" \
@" *\n" \
@" * All rights reserved.\n" \
@" *\n" \
@" * This file is part of ObjFW. It may be distributed under the terms " \
@"of the\n" \
Index: generators/unicode/TableGenerator.h
==================================================================
--- generators/unicode/TableGenerator.h
+++ generators/unicode/TableGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: generators/unicode/TableGenerator.m
==================================================================
--- generators/unicode/TableGenerator.m
+++ generators/unicode/TableGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -53,12 +53,12 @@
_titlecaseTableSize = SIZE_MAX;
_caseFoldingTableSize = SIZE_MAX;
_decompositionTableSize = SIZE_MAX;
_decompositionCompatTableSize = SIZE_MAX;
} @catch (id e) {
- @throw e;
[self release];
+ @throw e;
}
return self;
}
Index: generators/unicode/copyright.h
==================================================================
--- generators/unicode/copyright.h
+++ generators/unicode/copyright.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -15,11 +15,11 @@
#import "OFString.h"
#define COPYRIGHT \
@"/*\n" \
- @" * Copyright (c) 2008-2021 Jonathan Schleifer \n" \
+ @" * Copyright (c) 2008-2022 Jonathan Schleifer \n" \
@" *\n" \
@" * All rights reserved.\n" \
@" *\n" \
@" * This file is part of ObjFW. It may be distributed under the terms " \
@"of the\n" \
Index: objfw.spec
==================================================================
--- objfw.spec
+++ objfw.spec
@@ -1,15 +1,19 @@
%global libobjfw_major 0
%global libobjfw_minor 0
%global libobjfwrt_major 0
%global libobjfwrt_minor 0
+%global libobjfwtls_major 0
+%global libobjfwtls_minor 0
%if 0%{?suse_version}
%global libobjfw_pkgname libobjfw%{libobjfw_major}
%global libobjfwrt_pkgname libobjfwrt%{libobjfwrt_major}
+%global libobjfwtls_pkgname libobjfwtls%{libobjfwtls_major}
%else
%global libobjfw_pkgname libobjfw
%global libobjfwrt_pkgname libobjfwrt
+%global libobjfwtls_pkgname libobjfwtls
%endif
Name: objfw
Version: 1.1dev
Release: 1%{?dist}
@@ -26,10 +30,11 @@
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: clang
BuildRequires: make
+BuildRequires: pkgconfig(openssl)
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}
@@ -58,31 +63,46 @@
%description -n %{libobjfw_pkgname}
The %{libobjfw_pkgname} package contains the library needed by programs using
ObjFW.
%package -n %{libobjfw_pkgname}-devel
-Summary: Header files and tools for %{libobjfw_pkgname}
+Summary: Header files, libraries and tools for %{libobjfw_pkgname}
Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
Requires: %{libobjfwrt_pkgname}-devel = %{version}-%{release}
%description -n %{libobjfw_pkgname}-devel
-The %{libobjfw_pkgname}-devel package contains the header files and tools to
-develop programs using ObjFW.
+The %{libobjfw_pkgname}-devel package contains the header files, libraries and
+tools to develop programs using ObjFW.
%package -n %{libobjfwrt_pkgname}
Summary: ObjFW Objective-C runtime library
%description -n %{libobjfwrt_pkgname}
The %{libobjfwrt_pkgname} package contains ObjFW's Objective-C runtime library.
%package -n %{libobjfwrt_pkgname}-devel
-Summary: Header files for %{libobjfwrt_pkgname}
+Summary: Header files and libraries for %{libobjfwrt_pkgname}
Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
%description -n %{libobjfwrt_pkgname}-devel
-The %{libobjfwrt_pkgname}-devel package contains header files for ObjFW's
-Objective-C runtime library.
+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: openssl%{_isa} >= 1.1.1
+
+%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}
+
+%description -n %{libobjfwtls_pkgname}-devel
+The %{libobjfwtls_pkgname}-devel package contains header files and libraries
+for TLS support for ObjFW.
%package -n ofarc
Summary: Utility for handling ZIP, Tar and LHA archives
Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
@@ -113,10 +133,11 @@
%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 (via ObjOpenSSL) 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
@@ -125,11 +146,11 @@
%prep
%autosetup
./autogen.sh
%build
-%configure --disable-rpath
+%configure OBJC=clang --disable-rpath
%make_build
%install
%make_install
@@ -155,221 +176,12 @@
%license LICENSE.GPLv3
%license LICENSE.GPLv2
%files -n %{libobjfw_pkgname}-devel
%{_libdir}/libobjfw.so
-%{_includedir}/ObjFW/OFASPrintF.h
-%{_includedir}/ObjFW/OFAcceptFailedException.h
-%{_includedir}/ObjFW/OFAllocFailedException.h
-%{_includedir}/ObjFW/OFAlreadyConnectedException.h
-%{_includedir}/ObjFW/OFApplication.h
-%{_includedir}/ObjFW/OFArray.h
-%{_includedir}/ObjFW/OFAtomic.h
-%{_includedir}/ObjFW/OFBase64.h
-%{_includedir}/ObjFW/OFBindFailedException.h
-%{_includedir}/ObjFW/OFBlock.h
-%{_includedir}/ObjFW/OFCRC16.h
-%{_includedir}/ObjFW/OFCRC32.h
-%{_includedir}/ObjFW/OFChangeCurrentDirectoryPathFailedException.h
-%{_includedir}/ObjFW/OFCharacterSet.h
-%{_includedir}/ObjFW/OFChecksumMismatchException.h
-%{_includedir}/ObjFW/OFCollection.h
-%{_includedir}/ObjFW/OFColor.h
-%{_includedir}/ObjFW/OFCondition.h
-%{_includedir}/ObjFW/OFConditionBroadcastFailedException.h
-%{_includedir}/ObjFW/OFConditionSignalFailedException.h
-%{_includedir}/ObjFW/OFConditionStillWaitingException.h
-%{_includedir}/ObjFW/OFConditionWaitFailedException.h
-%{_includedir}/ObjFW/OFConnectionFailedException.h
-%{_includedir}/ObjFW/OFConstantString.h
-%{_includedir}/ObjFW/OFCopyItemFailedException.h
-%{_includedir}/ObjFW/OFCountedSet.h
-%{_includedir}/ObjFW/OFCreateDirectoryFailedException.h
-%{_includedir}/ObjFW/OFCreateSymbolicLinkFailedException.h
-%{_includedir}/ObjFW/OFCryptographicHash.h
-%{_includedir}/ObjFW/OFDNSQuery.h
-%{_includedir}/ObjFW/OFDNSQueryFailedException.h
-%{_includedir}/ObjFW/OFDNSResolver.h
-%{_includedir}/ObjFW/OFDNSResourceRecord.h
-%{_includedir}/ObjFW/OFDNSResponse.h
-%{_includedir}/ObjFW/OFData+CryptographicHashing.h
-%{_includedir}/ObjFW/OFData+MessagePackParsing.h
-%{_includedir}/ObjFW/OFData.h
-%{_includedir}/ObjFW/OFDatagramSocket.h
-%{_includedir}/ObjFW/OFDate.h
-%{_includedir}/ObjFW/OFDictionary.h
-%{_includedir}/ObjFW/OFEnumerationMutationException.h
-%{_includedir}/ObjFW/OFEnumerator.h
-%{_includedir}/ObjFW/OFException.h
-%{_includedir}/ObjFW/OFFile.h
-%{_includedir}/ObjFW/OFFileManager.h
-%{_includedir}/ObjFW/OFGZIPStream.h
-%{_includedir}/ObjFW/OFGetCurrentDirectoryPathFailedException.h
-%{_includedir}/ObjFW/OFGetOptionFailedException.h
-%{_includedir}/ObjFW/OFHMAC.h
-%{_includedir}/ObjFW/OFHTTPClient.h
-%{_includedir}/ObjFW/OFHTTPCookie.h
-%{_includedir}/ObjFW/OFHTTPCookieManager.h
-%{_includedir}/ObjFW/OFHTTPRequest.h
-%{_includedir}/ObjFW/OFHTTPRequestFailedException.h
-%{_includedir}/ObjFW/OFHTTPResponse.h
-%{_includedir}/ObjFW/OFHTTPServer.h
-%{_includedir}/ObjFW/OFHashAlreadyCalculatedException.h
-%{_includedir}/ObjFW/OFHuffmanTree.h
-%{_includedir}/ObjFW/OFINICategory.h
-%{_includedir}/ObjFW/OFINIFile.h
-%{_includedir}/ObjFW/OFIPXSocket.h
-%{_includedir}/ObjFW/OFInflate64Stream.h
-%{_includedir}/ObjFW/OFInflateStream.h
-%{_includedir}/ObjFW/OFInitializationFailedException.h
-%{_includedir}/ObjFW/OFInvalidArgumentException.h
-%{_includedir}/ObjFW/OFInvalidEncodingException.h
-%{_includedir}/ObjFW/OFInvalidFormatException.h
-%{_includedir}/ObjFW/OFInvalidJSONException.h
-%{_includedir}/ObjFW/OFInvalidServerReplyException.h
-%{_includedir}/ObjFW/OFInvocation.h
-%{_includedir}/ObjFW/OFJSONRepresentation.h
-%{_includedir}/ObjFW/OFKernelEventObserver.h
-%{_includedir}/ObjFW/OFKeyValueCoding.h
-%{_includedir}/ObjFW/OFLHAArchive.h
-%{_includedir}/ObjFW/OFLHAArchiveEntry.h
-%{_includedir}/ObjFW/OFLinkFailedException.h
-%{_includedir}/ObjFW/OFList.h
-%{_includedir}/ObjFW/OFListenFailedException.h
-%{_includedir}/ObjFW/OFLoadPluginFailedException.h
-%{_includedir}/ObjFW/OFLocale.h
-%{_includedir}/ObjFW/OFLockFailedException.h
-%{_includedir}/ObjFW/OFLocking.h
-%{_includedir}/ObjFW/OFMD5Hash.h
-%{_includedir}/ObjFW/OFMalformedXMLException.h
-%{_includedir}/ObjFW/OFMapTable.h
-%{_includedir}/ObjFW/OFMemoryNotPartOfObjectException.h
-%{_includedir}/ObjFW/OFMessagePackExtension.h
-%{_includedir}/ObjFW/OFMessagePackRepresentation.h
-%{_includedir}/ObjFW/OFMethodSignature.h
-%{_includedir}/ObjFW/OFMoveItemFailedException.h
-%{_includedir}/ObjFW/OFMutableArray.h
-%{_includedir}/ObjFW/OFMutableData.h
-%{_includedir}/ObjFW/OFMutableDictionary.h
-%{_includedir}/ObjFW/OFMutableLHAArchiveEntry.h
-%{_includedir}/ObjFW/OFMutablePair.h
-%{_includedir}/ObjFW/OFMutableSet.h
-%{_includedir}/ObjFW/OFMutableString.h
-%{_includedir}/ObjFW/OFMutableTarArchiveEntry.h
-%{_includedir}/ObjFW/OFMutableTriple.h
-%{_includedir}/ObjFW/OFMutableURL.h
-%{_includedir}/ObjFW/OFMutableZIPArchiveEntry.h
-%{_includedir}/ObjFW/OFMutex.h
-%{_includedir}/ObjFW/OFNotImplementedException.h
-%{_includedir}/ObjFW/OFNotOpenException.h
-%{_includedir}/ObjFW/OFNull.h
-%{_includedir}/ObjFW/OFNumber.h
-%{_includedir}/ObjFW/OFObject+KeyValueCoding.h
-%{_includedir}/ObjFW/OFObject+Serialization.h
-%{_includedir}/ObjFW/OFObject.h
-%{_includedir}/ObjFW/OFObserveFailedException.h
-%{_includedir}/ObjFW/OFOnce.h
-%{_includedir}/ObjFW/OFOpenItemFailedException.h
-%{_includedir}/ObjFW/OFOptionsParser.h
-%{_includedir}/ObjFW/OFOutOfMemoryException.h
-%{_includedir}/ObjFW/OFOutOfRangeException.h
-%{_includedir}/ObjFW/OFPBKDF2.h
-%{_includedir}/ObjFW/OFPair.h
-%{_includedir}/ObjFW/OFPlainCondition.h
-%{_includedir}/ObjFW/OFPlainMutex.h
-%{_includedir}/ObjFW/OFPlainThread.h
-%{_includedir}/ObjFW/OFPlugin.h
-%{_includedir}/ObjFW/OFRIPEMD160Hash.h
-%{_includedir}/ObjFW/OFReadFailedException.h
-%{_includedir}/ObjFW/OFReadOrWriteFailedException.h
-%{_includedir}/ObjFW/OFRecursiveMutex.h
-%{_includedir}/ObjFW/OFRemoveItemFailedException.h
-%{_includedir}/ObjFW/OFResolveHostFailedException.h
-%{_includedir}/ObjFW/OFRetrieveItemAttributesFailedException.h
-%{_includedir}/ObjFW/OFRunLoop.h
-%{_includedir}/ObjFW/OFSHA1Hash.h
-%{_includedir}/ObjFW/OFSHA224Hash.h
-%{_includedir}/ObjFW/OFSHA224Or256Hash.h
-%{_includedir}/ObjFW/OFSHA256Hash.h
-%{_includedir}/ObjFW/OFSHA384Hash.h
-%{_includedir}/ObjFW/OFSHA384Or512Hash.h
-%{_includedir}/ObjFW/OFSHA512Hash.h
-%{_includedir}/ObjFW/OFSPXSocket.h
-%{_includedir}/ObjFW/OFSPXStreamSocket.h
-%{_includedir}/ObjFW/OFScrypt.h
-%{_includedir}/ObjFW/OFSecureData.h
-%{_includedir}/ObjFW/OFSeekFailedException.h
-%{_includedir}/ObjFW/OFSeekableStream.h
-%{_includedir}/ObjFW/OFSequencedPacketSocket.h
-%{_includedir}/ObjFW/OFSerialization.h
-%{_includedir}/ObjFW/OFSet.h
-%{_includedir}/ObjFW/OFSetItemAttributesFailedException.h
-%{_includedir}/ObjFW/OFSetOptionFailedException.h
-%{_includedir}/ObjFW/OFSettings.h
-%{_includedir}/ObjFW/OFSocket.h
-%{_includedir}/ObjFW/OFSortedList.h
-%{_includedir}/ObjFW/OFStdIOStream.h
-%{_includedir}/ObjFW/OFStillLockedException.h
-%{_includedir}/ObjFW/OFStrPTime.h
-%{_includedir}/ObjFW/OFStream.h
-%{_includedir}/ObjFW/OFStreamSocket.h
-%{_includedir}/ObjFW/OFString+CryptographicHashing.h
-%{_includedir}/ObjFW/OFString+JSONParsing.h
-%{_includedir}/ObjFW/OFString+PathAdditions.h
-%{_includedir}/ObjFW/OFString+PropertyListParsing.h
-%{_includedir}/ObjFW/OFString+Serialization.h
-%{_includedir}/ObjFW/OFString+URLEncoding.h
-%{_includedir}/ObjFW/OFString+XMLEscaping.h
-%{_includedir}/ObjFW/OFString+XMLUnescaping.h
-%{_includedir}/ObjFW/OFString.h
-%{_includedir}/ObjFW/OFSystemInfo.h
-%{_includedir}/ObjFW/OFTCPSocket.h
-%{_includedir}/ObjFW/OFTLSKey.h
-%{_includedir}/ObjFW/OFTLSSocket.h
-%{_includedir}/ObjFW/OFTarArchive.h
-%{_includedir}/ObjFW/OFTarArchiveEntry.h
-%{_includedir}/ObjFW/OFThread.h
-%{_includedir}/ObjFW/OFThreadJoinFailedException.h
-%{_includedir}/ObjFW/OFThreadPool.h
-%{_includedir}/ObjFW/OFThreadStartFailedException.h
-%{_includedir}/ObjFW/OFThreadStillRunningException.h
-%{_includedir}/ObjFW/OFTimer.h
-%{_includedir}/ObjFW/OFTriple.h
-%{_includedir}/ObjFW/OFTruncatedDataException.h
-%{_includedir}/ObjFW/OFUDPSocket.h
-%{_includedir}/ObjFW/OFURL.h
-%{_includedir}/ObjFW/OFURLHandler.h
-%{_includedir}/ObjFW/OFUnboundNamespaceException.h
-%{_includedir}/ObjFW/OFUnboundPrefixException.h
-%{_includedir}/ObjFW/OFUndefinedKeyException.h
-%{_includedir}/ObjFW/OFUnknownXMLEntityException.h
-%{_includedir}/ObjFW/OFUnlockFailedException.h
-%{_includedir}/ObjFW/OFUnsupportedProtocolException.h
-%{_includedir}/ObjFW/OFUnsupportedVersionException.h
-%{_includedir}/ObjFW/OFValue.h
-%{_includedir}/ObjFW/OFWriteFailedException.h
-%{_includedir}/ObjFW/OFXMLAttribute.h
-%{_includedir}/ObjFW/OFXMLCDATA.h
-%{_includedir}/ObjFW/OFXMLCharacters.h
-%{_includedir}/ObjFW/OFXMLComment.h
-%{_includedir}/ObjFW/OFXMLElement+Serialization.h
-%{_includedir}/ObjFW/OFXMLElement.h
-%{_includedir}/ObjFW/OFXMLElementBuilder.h
-%{_includedir}/ObjFW/OFXMLNode.h
-%{_includedir}/ObjFW/OFXMLParser.h
-%{_includedir}/ObjFW/OFXMLProcessingInstruction.h
-%{_includedir}/ObjFW/OFZIPArchive.h
-%{_includedir}/ObjFW/OFZIPArchiveEntry.h
-%{_includedir}/ObjFW/ObjFW.h
-%{_includedir}/ObjFW/macros.h
-%{_includedir}/ObjFW/objfw-defs.h
-%{_includedir}/ObjFW/platform.h
-%{_includedir}/ObjFW/platform/GCC4.7/OFAtomic.h
-%{_includedir}/ObjFW/platform/GCC4/OFAtomic.h
-%{_includedir}/ObjFW/platform/PowerPC/OFAtomic.h
-%{_includedir}/ObjFW/platform/macOS/OFAtomic.h
-%{_includedir}/ObjFW/platform/x86/OFAtomic.h
+%dir %{_includedir}/ObjFW
+%{_includedir}/ObjFW
%{_bindir}/objfw-compile
%{_bindir}/objfw-config
%{_bindir}/objfw-new
%license LICENSE.QPL
%license LICENSE.GPLv3
@@ -384,10 +196,24 @@
%files -n %{libobjfwrt_pkgname}-devel
%{_libdir}/libobjfwrt.so
%{_includedir}/ObjFWRT/ObjFWRT.h
%license LICENSE.QPL
+%license LICENSE.GPLv3
+%license LICENSE.GPLv2
+
+%files -n %{libobjfwtls_pkgname}
+%{_libdir}/libobjfwtls.so.%{libobjfwtls_major}
+%{_libdir}/libobjfwtls.so.%{libobjfwtls_major}.%{libobjfwtls_minor}.0
+%license LICENSE.QPL
+%license LICENSE.GPLv3
+%license LICENSE.GPLv2
+
+%files -n %{libobjfwtls_pkgname}-devel
+%{_libdir}/libobjfwtls.so
+%{_includedir}/ObjFWTLS/ObjFWTLS.h
+%license LICENSE.QPL
%license LICENSE.GPLv3
%license LICENSE.GPLv2
%files -n ofarc
%{_bindir}/ofarc
Index: src/Makefile
==================================================================
--- src/Makefile
+++ src/Makefile
@@ -1,9 +1,9 @@
include ../extra.mk
SUBDIRS = ${RUNTIME} exceptions encodings forwarding
-SUBDIRS_AFTER = ${LINKLIB} ${BRIDGE}
+SUBDIRS_AFTER = ${LINKLIB} ${BRIDGE} ${TLS}
CLEAN = amiga-end.amigalib.dep \
amiga-end.amigalib.o \
amiga-glue.amigalib.dep \
amiga-glue.amigalib.o \
amiga-library-functable.inc \
@@ -17,40 +17,40 @@
FRAMEWORK = ${OBJFW_FRAMEWORK}
AMIGA_LIB = ${OBJFW_AMIGA_LIB}
LIB_MAJOR = ${OBJFW_LIB_MAJOR}
LIB_MINOR = ${OBJFW_LIB_MINOR}
-SRCS = OFASPrintF.m \
- OFApplication.m \
+SRCS = OFApplication.m \
OFArray.m \
- OFBase64.m \
OFBlock.m \
- OFCRC16.m \
- OFCRC32.m \
OFCharacterSet.m \
OFColor.m \
OFConstantString.m \
OFCountedSet.m \
OFData.m \
OFData+CryptographicHashing.m \
OFData+MessagePackParsing.m \
OFDate.m \
OFDictionary.m \
+ OFEmbeddedFileURLHandler.m \
OFEnumerator.m \
OFFileManager.m \
OFGZIPStream.m \
OFHMAC.m \
- OFHuffmanTree.m \
+ OFINICategory.m \
+ OFINIFile.m \
+ OFINIFileSettings.m \
OFInflate64Stream.m \
OFInflateStream.m \
OFInvocation.m \
OFLHAArchive.m \
OFLHAArchiveEntry.m \
OFList.m \
OFLocale.m \
OFMD5Hash.m \
OFMapTable.m \
+ OFMemoryStream.m \
OFMessagePackExtension.m \
OFMethodSignature.m \
OFMutableArray.m \
OFMutableData.m \
OFMutableDictionary.m \
@@ -60,10 +60,12 @@
OFMutableString.m \
OFMutableTarArchiveEntry.m \
OFMutableTriple.m \
OFMutableURL.m \
OFMutableZIPArchiveEntry.m \
+ OFNotification.m \
+ OFNotificationCenter.m \
OFNull.m \
OFNumber.m \
OFObject.m \
OFObject+KeyValueCoding.m \
OFObject+Serialization.m \
@@ -85,29 +87,30 @@
OFSeekableStream.m \
OFSerialization.m \
OFSet.m \
OFSortedList.m \
OFStdIOStream.m \
- OFStrPTime.m \
OFStream.m \
OFString.m \
OFString+CryptographicHashing.m \
OFString+JSONParsing.m \
OFString+PropertyListParsing.m \
OFString+Serialization.m \
OFString+URLEncoding.m \
OFString+XMLEscaping.m \
OFString+XMLUnescaping.m \
- ${OF_SUBUPROCESS_M} \
+ ${OF_SUBPROCESS_M} \
+ OFSettings.m \
OFSystemInfo.m \
OFTarArchive.m \
OFTarArchiveEntry.m \
OFThread.m \
OFTimer.m \
OFTriple.m \
OFURL.m \
OFURLHandler.m \
+ OFUUID.m \
OFValue.m \
OFXMLAttribute.m \
OFXMLCDATA.m \
OFXMLCharacters.m \
OFXMLComment.m \
@@ -123,17 +126,11 @@
${USE_SRCS_PLUGINS} \
${USE_SRCS_SOCKETS} \
${USE_SRCS_THREADS} \
${USE_SRCS_WINDOWS}
SRCS_FILES = OFFile.m \
- OFINICategory.m \
- OFINIFile.m \
- OFSettings.m \
OFString+PathAdditions.m
-SRCS_IPX = OFIPXSocket.m \
- OFSPXSocket.m \
- OFSPXStreamSocket.m
SRCS_PLUGINS = OFPlugin.m
SRCS_SOCKETS = OFDNSQuery.m \
OFDNSResolver.m \
OFDNSResourceRecord.m \
OFDNSResponse.m \
@@ -146,20 +143,26 @@
OFHTTPServer.m \
OFSequencedPacketSocket.m \
OFSocket.m \
OFStreamSocket.m \
OFTCPSocket.m \
+ OFTLSStream.m \
OFUDPSocket.m \
- ${USE_SRCS_IPX}
+ ${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 \
- OFThreadPool.m
+ OFTLSKey.m
SRCS_WINDOWS = OFWin32ConsoleStdIOStream.m \
OFWindowsRegistryKey.m
INCLUDES_ATOMIC = OFAtomic.h \
platform/GCC4/OFAtomic.h \
@@ -173,22 +176,26 @@
OFJSONRepresentation.h \
OFKernelEventObserver.h \
OFKeyValueCoding.h \
OFLocking.h \
OFMessagePackRepresentation.h \
- OFTLSSocket.h \
ObjFW.h \
macros.h \
objfw-defs.h \
platform.h \
${USE_INCLUDES_ATOMIC}
-SRCS += OFAdjacentArray.m \
+SRCS += OFASPrintF.m \
+ OFAdjacentArray.m \
OFAdjacentSubarray.m \
+ OFBase64.m \
OFBitSetCharacterSet.m \
OFBytesValue.m \
+ OFCRC16.m \
+ OFCRC32.m \
OFCountedMapTableSet.m \
+ OFHuffmanTree.m \
OFInvertedCharacterSet.m \
OFLHADecompressingStream.m \
OFMapTableDictionary.m \
OFMapTableSet.m \
OFMutableAdjacentArray.m \
@@ -201,24 +208,24 @@
OFRangeCharacterSet.m \
OFRangeValue.m \
OFRectValue.m \
OFSandbox.m \
OFSizeValue.m \
+ OFStrPTime.m \
OFSubarray.m \
OFUTF8String.m \
${LIBBASES_M} \
${RUNTIME_AUTORELEASE_M} \
${RUNTIME_INSTANCE_M} \
${UNICODE_M}
-SRCS_FILES += OFFileURLHandler.m \
- OFINIFileSettings.m
+SRCS_FILES += OFFileURLHandler.m
SRCS_SOCKETS += OFDNSResolverSettings.m \
+ ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \
OFHTTPURLHandler.m \
OFHostAddressResolver.m \
OFIPSocketAsyncConnector.m \
OFKernelEventObserver.m \
- ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \
${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \
${OF_POLL_KERNEL_EVENT_OBSERVER_M} \
${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \
OFTCPSocketSOCKS5Connector.m
Index: src/OFASPrintF.h
==================================================================
--- src/OFASPrintF.h
+++ src/OFASPrintF.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASPrintF.m
==================================================================
--- src/OFASPrintF.m
+++ src/OFASPrintF.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFAdjacentArray.h
==================================================================
--- src/OFAdjacentArray.h
+++ src/OFAdjacentArray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFAdjacentArray.m
==================================================================
--- src/OFAdjacentArray.m
+++ src/OFAdjacentArray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFAdjacentSubarray.h
==================================================================
--- src/OFAdjacentSubarray.h
+++ src/OFAdjacentSubarray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFAdjacentSubarray.m
==================================================================
--- src/OFAdjacentSubarray.m
+++ src/OFAdjacentSubarray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFApplication.h
==================================================================
--- src/OFApplication.h
+++ src/OFApplication.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -14,10 +14,11 @@
*/
#include
#import "OFObject.h"
+#import "OFNotification.h"
OF_ASSUME_NONNULL_BEGIN
/** @file */
@@ -26,10 +27,15 @@
@class OFMutableArray OF_GENERIC(ObjectType);
@class OFMutableDictionary OF_GENERIC(KeyType, ObjectType);
@class OFSandbox;
@class OFString;
+/**
+ * @brief A notification that will be sent when the application will terminate.
+ */
+extern const OFNotificationName OFApplicationWillTerminateNotification;
+
/**
* @brief Specify the class to be used as the application delegate.
*
* An instance of this class will be created and act as the application
* delegate.
@@ -143,10 +149,14 @@
* @brief A class which represents the application as an object.
*
* In order to create a new OFApplication, you should create a class conforming
* to the optional @ref OFApplicationDelegate protocol and put
* `OF_APPLICATION_DELEGATE(NameOfYourClass)` in the .m file of that class.
+ *
+ * When the application is about to be terminated,
+ * @ref OFApplicationDelegate#applicationWillTerminate will be called on the
+ * delegate and an @ref OFApplicationWillTerminateNotification will be sent.
*/
OF_SUBCLASSING_RESTRICTED
@interface OFApplication: OFObject
{
OFString *_programName;
Index: src/OFApplication.m
==================================================================
--- src/OFApplication.m
+++ src/OFApplication.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -30,10 +30,11 @@
#ifdef OF_AMIGAOS
# import "OFFile.h"
# import "OFFileManager.h"
#endif
#import "OFLocale.h"
+#import "OFNotificationCenter.h"
#import "OFPair.h"
#import "OFRunLoop+Private.h"
#import "OFRunLoop.h"
#import "OFSandbox.h"
#import "OFString.h"
@@ -73,21 +74,30 @@
OF_DIRECT_MEMBERS
@interface OFApplication ()
- (instancetype)of_init OF_METHOD_FAMILY(init);
- (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv;
#ifdef OF_WINDOWS
-- (void)of_setArgumentCount: (int)argc andWideArgumentValues: (wchar_t *[])argv;
+- (void)of_setArgumentCount: (int *)argc
+ andArgumentValues: (char **[])argv
+ andWideArgumentCount: (int)wargc
+ andWideArgumentValues: (wchar_t *[])wargv;
#endif
- (void)of_run;
@end
+const OFNotificationName OFApplicationWillTerminateNotification =
+ @"OFApplicationWillTerminateNotification";
static OFApplication *app = nil;
static void
atexitHandler(void)
{
id delegate = app.delegate;
+
+ [[OFNotificationCenter defaultCenter]
+ postNotificationName: OFApplicationWillTerminateNotification
+ object: app];
if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
[delegate applicationWillTerminate];
[delegate release];
@@ -111,11 +121,14 @@
app = [[OFApplication alloc] of_init];
#ifdef OF_WINDOWS
if ([OFSystemInfo isWindowsNT]) {
__wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si);
- [app of_setArgumentCount: wargc andWideArgumentValues: wargv];
+ [app of_setArgumentCount: argc
+ andArgumentValues: argv
+ andWideArgumentCount: wargc
+ andWideArgumentValues: wargv];
} else
#endif
[app of_setArgumentCount: argc andArgumentValues: argv];
app.delegate = delegate;
@@ -460,11 +473,11 @@
[_environment release];
[super dealloc];
}
-- (void)of_setArgumentCount: (int *)argc andArgumentValues: (char ***)argv
+- (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv
{
void *pool = objc_autoreleasePoolPush();
OFMutableArray *arguments;
OFStringEncoding encoding;
@@ -493,22 +506,28 @@
objc_autoreleasePoolPop(pool);
}
#ifdef OF_WINDOWS
-- (void)of_setArgumentCount: (int)argc andWideArgumentValues: (wchar_t **)argv
+- (void)of_setArgumentCount: (int *)argc
+ andArgumentValues: (char **[])argv
+ andWideArgumentCount: (int)wargc
+ andWideArgumentValues: (wchar_t *[])wargv
{
void *pool = objc_autoreleasePoolPush();
OFMutableArray *arguments;
- if (argc > 0) {
- _programName = [[OFString alloc] initWithUTF16String: argv[0]];
+ _argc = argc;
+ _argv = argv;
+
+ if (wargc > 0) {
+ _programName = [[OFString alloc] initWithUTF16String: wargv[0]];
arguments = [[OFMutableArray alloc] init];
- for (int i = 1; i < argc; i++)
+ for (int i = 1; i < wargc; i++)
[arguments addObject:
- [OFString stringWithUTF16String: argv[i]]];
+ [OFString stringWithUTF16String: wargv[i]]];
[arguments makeImmutable];
_arguments = arguments;
}
Index: src/OFArray+Private.h
==================================================================
--- src/OFArray+Private.h
+++ src/OFArray+Private.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFArray.h
==================================================================
--- src/OFArray.h
+++ src/OFArray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -180,13 +180,12 @@
*
* @param objects A C array of objects
* @param count The length of the C array
* @return A new autoreleased OFArray
*/
-+ (instancetype)
- arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
- count: (size_t)count;
++ (instancetype)arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
+ count: (size_t)count;
/**
* @brief Initializes an OFArray with the specified object.
*
* @param object An object
@@ -435,18 +434,10 @@
* @return A new array with the objects from the specified array added
*/
- (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObjectsFromArray:
(OFArray OF_GENERIC(ObjectType) *)array;
-/**
- * @brief Creates a new array with the specified object removed.
- *
- * @param object The object to remove
- * @return A new array with the specified object removed
- */
-- (OFArray OF_GENERIC(ObjectType) *)arrayByRemovingObject: (ObjectType)object;
-
#ifdef OF_HAVE_BLOCKS
/**
* @brief Executes a block for each object.
*
* @param block The block to execute for each object
Index: src/OFArray.m
==================================================================
--- src/OFArray.m
+++ src/OFArray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -813,18 +813,10 @@
[ret makeImmutable];
return ret;
}
-- (OFArray *)arrayByRemovingObject: (id)object
-{
- OFMutableArray *ret = [[self mutableCopy] autorelease];
- [ret removeObject: object];
- [ret makeImmutable];
- return ret;
-}
-
#ifdef OF_HAVE_BLOCKS
- (OFArray *)mappedArrayUsingBlock: (OFArrayMapBlock)block
{
OFArray *ret;
size_t count = self.count;
Index: src/OFAtomic.h
==================================================================
--- src/OFAtomic.h
+++ src/OFAtomic.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBase64.h
==================================================================
--- src/OFBase64.h
+++ src/OFBase64.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBase64.m
==================================================================
--- src/OFBase64.m
+++ src/OFBase64.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBitSetCharacterSet.h
==================================================================
--- src/OFBitSetCharacterSet.h
+++ src/OFBitSetCharacterSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBitSetCharacterSet.m
==================================================================
--- src/OFBitSetCharacterSet.m
+++ src/OFBitSetCharacterSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBlock.h
==================================================================
--- src/OFBlock.h
+++ src/OFBlock.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBlock.m
==================================================================
--- src/OFBlock.m
+++ src/OFBlock.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBytesValue.h
==================================================================
--- src/OFBytesValue.h
+++ src/OFBytesValue.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBytesValue.m
==================================================================
--- src/OFBytesValue.m
+++ src/OFBytesValue.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC16.h
==================================================================
--- src/OFCRC16.h
+++ src/OFCRC16.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC16.m
==================================================================
--- src/OFCRC16.m
+++ src/OFCRC16.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC32.h
==================================================================
--- src/OFCRC32.h
+++ src/OFCRC32.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC32.m
==================================================================
--- src/OFCRC32.m
+++ src/OFCRC32.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCharacterSet.h
==================================================================
--- src/OFCharacterSet.h
+++ src/OFCharacterSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCharacterSet.m
==================================================================
--- src/OFCharacterSet.m
+++ src/OFCharacterSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCollection.h
==================================================================
--- src/OFCollection.h
+++ src/OFCollection.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFColor.h
==================================================================
--- src/OFColor.h
+++ src/OFColor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFColor.m
==================================================================
--- src/OFColor.m
+++ src/OFColor.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCondition.h
==================================================================
--- src/OFCondition.h
+++ src/OFCondition.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCondition.m
==================================================================
--- src/OFCondition.m
+++ src/OFCondition.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFConstantString.h
==================================================================
--- src/OFConstantString.h
+++ src/OFConstantString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFConstantString.m
==================================================================
--- src/OFConstantString.m
+++ src/OFConstantString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -347,10 +347,16 @@
- (OFString *)stringByAppendingPathComponent: (OFString *)component
{
[self finishInitialization];
return [self stringByAppendingPathComponent: component];
}
+
+- (OFString *)stringByAppendingPathExtension: (OFString *)extension
+{
+ [self finishInitialization];
+ return [self stringByAppendingPathExtension: extension];
+}
- (OFString *)stringByPrependingString: (OFString *)string
{
[self finishInitialization];
return [self stringByPrependingString: string];
Index: src/OFCountedMapTableSet.h
==================================================================
--- src/OFCountedMapTableSet.h
+++ src/OFCountedMapTableSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCountedMapTableSet.m
==================================================================
--- src/OFCountedMapTableSet.m
+++ src/OFCountedMapTableSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -41,11 +41,11 @@
@try {
void *pool = objc_autoreleasePoolPush();
if ([set isKindOfClass: [OFCountedSet class]]) {
- OFCountedSet *countedSet = (OFCountedSet *)countedSet;
+ OFCountedSet *countedSet = (OFCountedSet *)set;
for (id object in countedSet) {
size_t count =
[countedSet countForObject: object];
Index: src/OFCountedSet.h
==================================================================
--- src/OFCountedSet.h
+++ src/OFCountedSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCountedSet.m
==================================================================
--- src/OFCountedSet.m
+++ src/OFCountedSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCryptographicHash.h
==================================================================
--- src/OFCryptographicHash.h
+++ src/OFCryptographicHash.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -98,10 +98,15 @@
* @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
* you are still interested in the previous digest, you need to memcpy
Index: src/OFDNSQuery.h
==================================================================
--- src/OFDNSQuery.h
+++ src/OFDNSQuery.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSQuery.m
==================================================================
--- src/OFDNSQuery.m
+++ src/OFDNSQuery.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSResolver.h
==================================================================
--- src/OFDNSResolver.h
+++ src/OFDNSResolver.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSResolver.m
==================================================================
--- src/OFDNSResolver.m
+++ src/OFDNSResolver.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -37,10 +37,11 @@
#import "OFDNSQueryFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFInvalidServerReplyException.h"
+#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"
#ifndef SOCK_DNS
# define SOCK_DNS 0
@@ -745,11 +746,15 @@
OFSocketAddressParseIPv6(@"::", 0);
_IPv6Socket = [[OFUDPSocket alloc] init];
[_IPv6Socket of_bindToAddress: &address
extraType: SOCK_DNS];
- _IPv6Socket.canBlock = false;
+ @try {
+ _IPv6Socket.canBlock = false;
+ } @catch (OFNotImplementedException *e) {
+ /* Can't do anything about it... */
+ }
_IPv6Socket.delegate = self;
}
sock = _IPv6Socket;
break;
@@ -760,11 +765,15 @@
OFSocketAddressParseIPv4(@"0.0.0.0", 0);
_IPv4Socket = [[OFUDPSocket alloc] init];
[_IPv4Socket of_bindToAddress: &address
extraType: SOCK_DNS];
- _IPv4Socket.canBlock = false;
+ @try {
+ _IPv4Socket.canBlock = false;
+ } @catch (OFNotImplementedException *e) {
+ /* Can't do anything about it... */
+ }
_IPv4Socket.delegate = self;
}
sock = _IPv4Socket;
break;
Index: src/OFDNSResolverSettings.h
==================================================================
--- src/OFDNSResolverSettings.h
+++ src/OFDNSResolverSettings.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSResolverSettings.m
==================================================================
--- src/OFDNSResolverSettings.m
+++ src/OFDNSResolverSettings.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -64,10 +64,14 @@
# define RESOLV_CONF_PATH @"AmiTCP:db/resolv.conf"
#else
# define HOSTS_PATH @"/etc/hosts"
# define RESOLV_CONF_PATH @"/etc/resolv.conf"
#endif
+
+#ifndef HOST_NAME_MAX
+# define HOST_NAME_MAX 255
+#endif
#ifndef OF_WII
static OFString *
domainFromHostname(OFString *hostname)
{
@@ -100,13 +104,13 @@
#if !defined(OF_WII) && !defined(OF_MORPHOS)
static OFString *
obtainHostname(void)
{
- char hostname[256];
+ char hostname[HOST_NAME_MAX + 1];
- if (gethostname(hostname, 256) != 0)
+ if (gethostname(hostname, HOST_NAME_MAX + 1) != 0)
return nil;
return [OFString stringWithCString: hostname
encoding: [OFLocale encoding]];
}
Index: src/OFDNSResourceRecord.h
==================================================================
--- src/OFDNSResourceRecord.h
+++ src/OFDNSResourceRecord.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSResourceRecord.m
==================================================================
--- src/OFDNSResourceRecord.m
+++ src/OFDNSResourceRecord.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSResponse.h
==================================================================
--- src/OFDNSResponse.h
+++ src/OFDNSResponse.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSResponse.m
==================================================================
--- src/OFDNSResponse.m
+++ src/OFDNSResponse.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -54,11 +54,11 @@
}
return self;
}
-- (instancetype)init OF_UNAVAILABLE
+- (instancetype)init
{
OF_INVALID_INIT_METHOD
}
- (void)dealloc
Index: src/OFData+CryptographicHashing.h
==================================================================
--- src/OFData+CryptographicHashing.h
+++ src/OFData+CryptographicHashing.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFData+CryptographicHashing.m
==================================================================
--- src/OFData+CryptographicHashing.m
+++ src/OFData+CryptographicHashing.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -39,10 +39,11 @@
const unsigned char *digest;
char cString[digestSize * 2];
[hash updateWithBuffer: self->_items
length: self->_count * self->_itemSize];
+ [hash calculate];
digest = hash.digest;
for (size_t i = 0; i < digestSize; i++) {
uint8_t high, low;
Index: src/OFData+MessagePackParsing.h
==================================================================
--- src/OFData+MessagePackParsing.h
+++ src/OFData+MessagePackParsing.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFData+MessagePackParsing.m
==================================================================
--- src/OFData+MessagePackParsing.m
+++ src/OFData+MessagePackParsing.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFData.h
==================================================================
--- src/OFData.h
+++ src/OFData.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -43,15 +43,15 @@
* for OFData with item size 1.
*/
@interface OFData: OFObject
{
- unsigned char *_items;
+ unsigned char *_Nullable _items;
size_t _count, _itemSize;
bool _freeWhenDone;
@private
- OFData *_parentData;
+ OFData *_Nullable _parentData;
OF_RESERVE_IVARS(OFData, 4)
}
/**
* @brief The size of a single item in the OFData in bytes.
@@ -66,11 +66,12 @@
/**
* @brief All elements of the OFData as a C array.
*
* @warning The pointer is only valid until the OFData is changed!
*/
-@property (readonly, nonatomic) const void *items OF_RETURNS_INNER_POINTER;
+@property OF_NULLABLE_PROPERTY (readonly, nonatomic) const void *items
+ OF_RETURNS_INNER_POINTER;
/**
* @brief The first item of the OFData or `NULL`.
*/
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) const void *firstItem
@@ -173,13 +174,13 @@
*/
+ (instancetype)dataWithContentsOfURL: (OFURL *)URL;
/**
* @brief Creates a new OFData with an item size of 1, containing the data of
- * the string representation.
+ * the hex string representation.
*
- * @param string The string representation of the data
+ * @param string The hex string representation of the data
* @return A new autoreleased OFData
*/
+ (instancetype)dataWithStringRepresentation: (OFString *)string;
/**
@@ -190,21 +191,21 @@
* @return A new autoreleased OFData
*/
+ (instancetype)dataWithBase64EncodedString: (OFString *)string;
/**
- * @brief Initialized an already allocated OFData with the specified `count`
+ * @brief Initializes an already allocated OFData with the specified `count`
* items of size 1.
*
* @param items The items to store in the OFData
* @param count The number of items
* @return An initialized OFData
*/
- (instancetype)initWithItems: (const void *)items count: (size_t)count;
/**
- * @brief Initialized an already allocated OFData with the specified `count`
+ * @brief Initializes an already allocated OFData with the specified `count`
* items of the specified size.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param itemSize The item size of a single item in bytes
@@ -272,13 +273,13 @@
*/
- (instancetype)initWithContentsOfURL: (OFURL *)URL;
/**
* @brief Initializes an already allocated OFData with an item size of 1,
- * containing the data of the string representation.
+ * containing the data of the hex string representation.
*
- * @param string The string representation of the data
+ * @param string The hex string representation of the data
* @return A new autoreleased OFData
*/
- (instancetype)initWithStringRepresentation: (OFString *)string;
/**
Index: src/OFData.m
==================================================================
--- src/OFData.m
+++ src/OFData.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDatagramSocket.h
==================================================================
--- src/OFDatagramSocket.h
+++ src/OFDatagramSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -39,18 +39,15 @@
const OFSocketAddress *_Nonnull sender, id _Nullable exception);
/**
* @brief A block which is called when a packet has been sent.
*
- * @param data The data which was sent
- * @param receiver The receiver for the packet
* @param exception An exception which occurred while reading or `nil` on
* success
* @return The data to repeat the send with or nil if it should not repeat
*/
typedef OFData *_Nullable (^OFDatagramSocketAsyncSendDataBlock)(
- OFData *_Nonnull data, const OFSocketAddress *_Nonnull receiver,
id _Nullable exception);
#endif
/**
* @protocol OFDatagramSocketDelegate OFDatagramSocket.h \
Index: src/OFDatagramSocket.m
==================================================================
--- src/OFDatagramSocket.m
+++ src/OFDatagramSocket.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -175,35 +175,40 @@
sender->length = (socklen_t)sizeof(sender->sockaddr);
#ifndef OF_WINDOWS
if ((ret = recvfrom(_socket, buffer, length, 0,
- &sender->sockaddr.sockaddr, &sender->length)) < 0)
+ (struct sockaddr *)&sender->sockaddr, &sender->length)) < 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->sockaddr.sockaddr, &sender->length)) < 0)
+ (struct sockaddr *)&sender->sockaddr, &sender->length)) < 0)
@throw [OFReadFailedException
exceptionWithObject: self
requestedLength: length
errNo: OFSocketErrNo()];
#endif
- switch (sender->sockaddr.sockaddr.sa_family) {
+ 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;
@@ -274,12 +279,11 @@
if (length > SSIZE_MAX)
@throw [OFOutOfRangeException exception];
if ((bytesWritten = sendto(_socket, (void *)buffer, length, 0,
- (struct sockaddr *)&receiver->sockaddr.sockaddr,
- receiver->length)) < 0)
+ (struct sockaddr *)&receiver->sockaddr, receiver->length)) < 0)
@throw [OFWriteFailedException
exceptionWithObject: self
requestedLength: length
bytesWritten: 0
errNo: OFSocketErrNo()];
@@ -288,11 +292,11 @@
if (length > INT_MAX)
@throw [OFOutOfRangeException exception];
if ((bytesWritten = sendto(_socket, buffer, (int)length, 0,
- &receiver->sockaddr.sockaddr, receiver->length)) < 0)
+ (struct sockaddr *)&receiver->sockaddr, receiver->length)) < 0)
@throw [OFWriteFailedException
exceptionWithObject: self
requestedLength: length
bytesWritten: 0
errNo: OFSocketErrNo()];
Index: src/OFDate.h
==================================================================
--- src/OFDate.h
+++ src/OFDate.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDate.m
==================================================================
--- src/OFDate.m
+++ src/OFDate.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -39,12 +39,12 @@
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
-#ifdef OF_AMIGAOS_M68K
-/* amiga-gcc does not have trunc() */
+#if defined(OF_AMIGAOS_M68K) || defined(OF_MINT)
+/* amiga-gcc and freemint-gcc do not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif
@interface OFDate ()
+ (instancetype)of_alloc;
Index: src/OFDictionary.h
==================================================================
--- src/OFDictionary.h
+++ src/OFDictionary.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -32,12 +32,36 @@
OF_ASSUME_NONNULL_BEGIN
@class OFArray OF_GENERIC(ObjectType);
#ifdef OF_HAVE_BLOCKS
+/**
+ * @brief A block for enumerating an OFDictionary.
+ *
+ * @param key The current key
+ * @param object The object for the current key
+ * @param stop A pointer to a variable that can be set to true to stop the
+ * enumeration.
+ */
typedef void (^OFDictionaryEnumerationBlock)(id key, id object, bool *stop);
+
+/**
+ * @brief A block for filtering an OFDictionary.
+ *
+ * @param key The key to inspect
+ * @param object The object for the key to inspect
+ * @return Whether the object should be in the filtered dictionary.
+ */
typedef bool (^OFDictionaryFilterBlock)(id key, id object);
+
+/**
+ * @brief A block for mapping keys to objects in an OFDictionary.
+ *
+ * @param key The key to map
+ * @param object The current object for the key
+ * @return The object to map the key to
+ */
typedef id _Nonnull (^OFDictionaryMapBlock)(id key, id object);
#endif
/**
* @class OFDictionary OFDictionary.h ObjFW/OFDictionary.h
@@ -104,13 +128,12 @@
*
* @param keys An array of keys
* @param objects An array of objects
* @return A new autoreleased OFDictionary
*/
-+ (instancetype)
- dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects
- forKeys: (OFArray OF_GENERIC(KeyType) *)keys;
++ (instancetype)dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects
+ forKeys: (OFArray OF_GENERIC(KeyType) *)keys;
/**
* @brief Creates a new OFDictionary with the specified keys and objects.
*
* @param keys An array of keys
Index: src/OFDictionary.m
==================================================================
--- src/OFDictionary.m
+++ src/OFDictionary.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
ADDED src/OFEmbeddedFileURLHandler.h
Index: src/OFEmbeddedFileURLHandler.h
==================================================================
--- src/OFEmbeddedFileURLHandler.h
+++ src/OFEmbeddedFileURLHandler.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2008-2022 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFURLHandler.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFEmbeddedFileURLHandler: OFURLHandler
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFEmbeddedFileURLHandler.m
Index: src/OFEmbeddedFileURLHandler.m
==================================================================
--- src/OFEmbeddedFileURLHandler.m
+++ src/OFEmbeddedFileURLHandler.m
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2008-2022 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+
+#import "OFEmbeddedFileURLHandler.h"
+#import "OFMemoryStream.h"
+#import "OFURL.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFOpenItemFailedException.h"
+
+#ifdef OF_HAVE_THREADS
+# import "OFOnce.h"
+# import "OFPlainMutex.h"
+#endif
+
+struct EmbeddedFile {
+ const char *name;
+ const uint8_t *bytes;
+ size_t size;
+} *embeddedFiles = NULL;
+size_t numEmbeddedFiles = 0;
+#ifdef OF_HAVE_THREADS
+static OFPlainMutex mutex;
+
+static void
+init(void)
+{
+ OFEnsure(OFPlainMutexNew(&mutex) == 0);
+}
+#endif
+
+void
+OFRegisterEmbeddedFile(const char *name, const uint8_t *bytes, size_t size)
+{
+#ifdef OF_HAVE_THREADS
+ static OFOnceControl onceControl = OFOnceControlInitValue;
+ OFOnce(&onceControl, init);
+
+ OFEnsure(OFPlainMutexLock(&mutex) == 0);
+#endif
+
+ embeddedFiles = realloc(embeddedFiles,
+ sizeof(*embeddedFiles) * (numEmbeddedFiles + 1));
+ OFEnsure(embeddedFiles != NULL);
+
+ embeddedFiles[numEmbeddedFiles].name = name;
+ embeddedFiles[numEmbeddedFiles].bytes = bytes;
+ embeddedFiles[numEmbeddedFiles].size = size;
+ numEmbeddedFiles++;
+
+#ifdef OF_HAVE_THREADS
+ OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
+#endif
+}
+
+@implementation OFEmbeddedFileURLHandler
+- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode
+{
+ const char *path;
+
+ if (![URL.scheme isEqual: @"objfw-embedded"] || URL.host != nil ||
+ URL.port != nil || URL.user != nil || URL.password != nil ||
+ URL.query != nil || URL.fragment != nil)
+ @throw [OFInvalidArgumentException exception];
+
+ if (![mode isEqual: @"r"])
+ @throw [OFOpenItemFailedException exceptionWithURL: URL
+ mode: mode
+ errNo: EROFS];
+
+ if ((path = URL.path.UTF8String) == NULL) {
+ @throw [OFInvalidArgumentException exception];
+ }
+
+#ifdef OF_HAVE_THREADS
+ OFEnsure(OFPlainMutexLock(&mutex) == 0);
+ @try {
+#endif
+ for (size_t i = 0; i < numEmbeddedFiles; i++) {
+ if (strcmp(embeddedFiles[i].name, path) != 0)
+ continue;
+
+ return [OFMemoryStream
+ streamWithMemoryAddress: (void *)
+ embeddedFiles[i].bytes
+ size: embeddedFiles[i].size
+ writable: false];
+ }
+#ifdef OF_HAVE_THREADS
+ } @finally {
+ OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
+ }
+#endif
+
+ @throw [OFOpenItemFailedException exceptionWithURL: URL
+ mode: mode
+ errNo: ENOENT];
+}
+@end
Index: src/OFEnumerator.h
==================================================================
--- src/OFEnumerator.h
+++ src/OFEnumerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -48,12 +48,10 @@
/**
* @struct OFFastEnumerationState OFEnumerator.h ObjFW/OFEnumerator.h
*
* @brief State information for fast enumerations.
*/
-#define OFFastEnumerationState NSFastEnumerationState
-#ifndef NSINTEGER_DEFINED
typedef struct {
/** Arbitrary state information for the enumeration */
unsigned long state;
/** Pointer to a C array of objects to return */
id __unsafe_unretained _Nullable *_Nullable itemsPtr;
@@ -60,10 +58,12 @@
/** Arbitrary state information to detect mutations */
unsigned long *_Nullable mutationsPtr;
/** Additional arbitrary state information */
unsigned long extra[5];
} OFFastEnumerationState;
+#ifndef NSINTEGER_DEFINED
+typedef OFFastEnumerationState NSFastEnumerationState;
#endif
/**
* @protocol OFFastEnumeration OFEnumerator.h ObjFW/OFEnumerator.h
*
Index: src/OFEnumerator.m
==================================================================
--- src/OFEnumerator.m
+++ src/OFEnumerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFEpollKernelEventObserver.h
==================================================================
--- src/OFEpollKernelEventObserver.h
+++ src/OFEpollKernelEventObserver.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFEpollKernelEventObserver.m
==================================================================
--- src/OFEpollKernelEventObserver.m
+++ src/OFEpollKernelEventObserver.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFFile.h
==================================================================
--- src/OFFile.h
+++ src/OFFile.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -63,30 +63,10 @@
* `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 URL and mode.
- *
- * @param URL The URL to the file to open
- * @param mode The mode in which the file should be opened.@n
- * Possible modes are:
- * Mode | Description
- * ---------------|-------------------------------------
- * `r` | Read-only
- * `r+` | Read-write
- * `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)fileWithURL: (OFURL *)URL mode: (OFString *)mode;
-
/**
* @brief Creates a new OFFile with the specified native file handle.
*
* @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this
* is a file descriptor. The handle is closed when the OFFile
@@ -93,12 +73,10 @@
* object is deallocated!
* @return A new autoreleased OFFile
*/
+ (instancetype)fileWithHandle: (OFFileHandle)handle;
-- (instancetype)init OF_UNAVAILABLE;
-
/**
* @brief Initializes an already allocated OFFile.
*
* @param path The path to the file to open as a string
* @param mode The mode in which the file should be opened.@n
@@ -122,38 +100,16 @@
- (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode;
/**
* @brief Initializes an already allocated OFFile.
*
- * @param URL The URL to the file to open
- * @param mode The mode in which the file should be opened.@n
- * Possible modes are:
- * Mode | Description
- * ---------------|-------------------------------------
- * `r` | read-only
- * `rb` | read-only, binary
- * `r+` | read-write
- * `rb+` or `r+b` | read-write, binary
- * `w` | write-only, create, truncate
- * `wb` | write-only, create, truncate, binary
- * `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)initWithURL: (OFURL *)URL mode: (OFString *)mode;
-
-/**
- * @brief Initializes an already allocated OFFile.
- *
* @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this
* is a file descriptor. The handle is closed when the OFFile
* object is deallocated!
* @return An initialized OFFile
*/
- (instancetype)initWithHandle: (OFFileHandle)handle OF_DESIGNATED_INITIALIZER;
+
+- (instancetype)init OF_UNAVAILABLE;
@end
OF_ASSUME_NONNULL_END
Index: src/OFFile.m
==================================================================
--- src/OFFile.m
+++ src/OFFile.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -46,10 +46,15 @@
#import "OFWriteFailedException.h"
#ifdef OF_WINDOWS
# include
#endif
+
+#ifdef OF_AMIGAOS
+# include
+# include
+#endif
#ifdef OF_WII
# include
#endif
@@ -56,13 +61,14 @@
#ifdef OF_NINTENDO_DS
# include
# include
#endif
-#ifdef OF_AMIGAOS
-# include
-# include
+#ifdef OF_NINTENDO_SWITCH
+# define id nx_id
+# include
+# undef id
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif
@@ -182,32 +188,31 @@
#ifdef OF_NINTENDO_DS
if (!nitroFSInit(NULL))
@throw [OFInitializationFailedException
exceptionWithClass: self];
#endif
+
+#ifdef OF_NINTENDO_SWITCH
+ if (R_SUCCEEDED(romfsInit()))
+ /*
+ * Errors are intentionally ignored, as it's possible we just
+ * have no romfs.
+ */
+ atexit((void (*)(void))romfsExit);
+#endif
}
+ (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode
{
return [[[self alloc] initWithPath: path mode: mode] autorelease];
}
-+ (instancetype)fileWithURL: (OFURL *)URL mode: (OFString *)mode
-{
- return [[[self alloc] initWithURL: URL mode: mode] autorelease];
-}
-
+ (instancetype)fileWithHandle: (OFFileHandle)handle
{
return [[[self alloc] initWithHandle: handle] autorelease];
}
-- (instancetype)init
-{
- OF_INVALID_INIT_METHOD
-}
-
- (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode
{
OFFileHandle handle;
@try {
@@ -327,37 +332,23 @@
}
return self;
}
-- (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode
-{
- void *pool = objc_autoreleasePoolPush();
- OFString *fileSystemRepresentation;
-
- @try {
- fileSystemRepresentation = URL.fileSystemRepresentation;
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- self = [self initWithPath: fileSystemRepresentation mode: mode];
-
- objc_autoreleasePoolPop(pool);
-
- return self;
-}
-
- (instancetype)initWithHandle: (OFFileHandle)handle
{
self = [super init];
_handle = handle;
return self;
}
+
+- (instancetype)init
+{
+ OF_INVALID_INIT_METHOD
+}
- (bool)lowlevelIsAtEndOfStream
{
if (_handle == OFInvalidFileHandle)
@throw [OFNotOpenException exceptionWithObject: self];
Index: src/OFFileManager.h
==================================================================
--- src/OFFileManager.h
+++ src/OFFileManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFFileManager.m
==================================================================
--- src/OFFileManager.m
+++ src/OFFileManager.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -65,10 +65,14 @@
#ifdef OF_AMIGAOS
# include
# include
#endif
+
+#ifdef OF_MINT
+# include
+#endif
@interface OFDefaultFileManager: OFFileManager
@end
#ifdef OF_AMIGAOS4
Index: src/OFFileManagerConstants.inc
==================================================================
--- src/OFFileManagerConstants.inc
+++ src/OFFileManagerConstants.inc
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFFileURLHandler.h
==================================================================
--- src/OFFileURLHandler.h
+++ src/OFFileURLHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFFileURLHandler.m
==================================================================
--- src/OFFileURLHandler.m
+++ src/OFFileURLHandler.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFGZIPStream.h
==================================================================
--- src/OFGZIPStream.h
+++ src/OFGZIPStream.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFGZIPStream.m
==================================================================
--- src/OFGZIPStream.m
+++ src/OFGZIPStream.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHMAC.h
==================================================================
--- src/OFHMAC.h
+++ src/OFHMAC.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -101,10 +101,15 @@
* @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
* be calculated efficiently. If you want to reset both, use
Index: src/OFHMAC.m
==================================================================
--- src/OFHMAC.m
+++ src/OFHMAC.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -17,10 +17,11 @@
#import "OFHMAC.h"
#import "OFSecureData.h"
#import "OFHashAlreadyCalculatedException.h"
+#import "OFHashNotCalculatedException.h"
#import "OFInvalidArgumentException.h"
@implementation OFHMAC
@synthesize hashClass = _hashClass;
@synthesize allowsSwappableMemory = _allowsSwappableMemory;
@@ -82,10 +83,11 @@
if (length > blockSize) {
id hash = [_hashClass
hashWithAllowsSwappableMemory:
_allowsSwappableMemory];
[hash updateWithBuffer: key length: length];
+ [hash calculate];
length = hash.digestSize;
if OF_UNLIKELY (length > blockSize)
length = blockSize;
@@ -138,21 +140,30 @@
exceptionWithObject: self];
[_innerHash updateWithBuffer: buffer length: length];
}
-- (const unsigned char *)digest
+- (void)calculate
{
+ if (_calculated)
+ @throw [OFHashAlreadyCalculatedException
+ exceptionWithObject: self];
+
if (_outerHash == nil || _innerHash == nil)
@throw [OFInvalidArgumentException exception];
- if (_calculated)
- return _outerHash.digest;
-
+ [_innerHash calculate];
[_outerHash updateWithBuffer: _innerHash.digest
length: _innerHash.digestSize];
+ [_outerHash calculate];
_calculated = true;
+}
+
+- (const unsigned char *)digest
+{
+ if (!_calculated)
+ @throw [OFHashNotCalculatedException exceptionWithObject: self];
return _outerHash.digest;
}
- (size_t)digestSize
Index: src/OFHTTPClient.h
==================================================================
--- src/OFHTTPClient.h
+++ src/OFHTTPClient.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -25,10 +25,11 @@
@class OFHTTPClient;
@class OFHTTPRequest;
@class OFHTTPResponse;
@class OFStream;
@class OFTCPSocket;
+@class OFTLSStream;
@class OFURL;
/**
* @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h
*
@@ -48,24 +49,36 @@
response: (nullable OFHTTPResponse *)response
exception: (nullable id)exception;
@optional
/**
- * @brief A callback which is called when an OFHTTPClient creates a socket.
- *
- * This is useful if the connection is using HTTPS and the server requires a
- * client certificate. This callback can then be used to tell the TLS socket
- * about the certificate. Another use case is to tell the socket about a SOCKS5
- * proxy it should use for this connection.
- *
- * @param client The OFHTTPClient that created a socket
- * @param socket The socket created by the OFHTTPClient
- * @param request The request for which the socket was created
- */
-- (void)client: (OFHTTPClient *)client
- didCreateSocket: (OFTCPSocket *)socket
- request: (OFHTTPRequest *)request;
+ * @brief A callback which is called when an OFHTTPClient creates a TCP socket.
+ *
+ * This can be used to tell the socket about a SOCKS5 proxy it should use for
+ * this connection.
+ *
+ * @param client The OFHTTPClient that created a TCP socket
+ * @param TCPSocket The socket created by the OFHTTPClient
+ * @param request The request for which the TCP socket was created
+ */
+- (void)client: (OFHTTPClient *)client
+ didCreateTCPSocket: (OFTCPSocket *)TCPSocket
+ request: (OFHTTPRequest *)request;
+
+/**
+ * @brief A callback which is called when an OFHTTPClient creates a TLS stream.
+ *
+ * This can be used to tell the TLS stream about a client certificate it should
+ * use before performing the TLS handshake.
+ *
+ * @param client The OFHTTPClient that created a TLS stream
+ * @param TLSStream The TLS stream created by the OFHTTPClient
+ * @param request The request for which the TLS stream was created
+ */
+- (void)client: (OFHTTPClient *)client
+ didCreateTLSStream: (OFTLSStream *)TLSStream
+ request: (OFHTTPRequest *)request;
/**
* @brief A callback which is called when an OFHTTPClient wants to send the
* body for a request.
*
@@ -134,11 +147,11 @@
#ifdef OF_HTTPCLIENT_M
@public
#endif
OFObject *_Nullable _delegate;
bool _allowsInsecureRedirects, _inProgress;
- OFTCPSocket *_Nullable _socket;
+ OFStream *_Nullable _stream;
OFURL *_Nullable _lastURL;
bool _lastWasHEAD;
OFHTTPResponse *_Nullable _lastResponse;
}
Index: src/OFHTTPClient.m
==================================================================
--- src/OFHTTPClient.m
+++ src/OFHTTPClient.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -26,13 +26,13 @@
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFKernelEventObserver.h"
#import "OFNumber.h"
#import "OFRunLoop.h"
-#import "OFSocket+Private.h"
#import "OFString.h"
#import "OFTCPSocket.h"
+#import "OFTLSStream.h"
#import "OFURL.h"
#import "OFAlreadyConnectedException.h"
#import "OFHTTPRequestFailedException.h"
#import "OFInvalidArgumentException.h"
@@ -49,11 +49,12 @@
#import "OFWriteFailedException.h"
static const unsigned int defaultRedirects = 10;
OF_DIRECT_MEMBERS
-@interface OFHTTPClientRequestHandler: OFObject
+@interface OFHTTPClientRequestHandler: OFObject
{
@public
OFHTTPClient *_client;
OFHTTPRequest *_request;
unsigned int _redirects;
@@ -72,32 +73,32 @@
OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestBodyStream: OFStream
{
OFHTTPClientRequestHandler *_handler;
- OFTCPSocket *_socket;
+ OFStream *_stream;
bool _chunked;
unsigned long long _toWrite;
bool _atEndOfStream;
}
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
- socket: (OFTCPSocket *)sock;
+ stream: (OFStream *)stream;
@end
OF_DIRECT_MEMBERS
@interface OFHTTPClientResponse: OFHTTPResponse
{
- OFTCPSocket *_socket;
+ OFStream *_stream;
bool _hasContentLength, _chunked, _keepAlive;
bool _atEndOfStream, _setAtEndOfStream;
long long _toRead;
}
@property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive;
-- (instancetype)initWithSocket: (OFTCPSocket *)sock;
+- (instancetype)initWithStream: (OFStream *)stream;
@end
OF_DIRECT_MEMBERS
@interface OFHTTPClientSyncPerformer: OFObject
{
@@ -293,20 +294,20 @@
didPerformRequest: _request
response: nil
exception: exception];
}
-- (void)createResponseWithSocketOrThrow: (OFTCPSocket *)sock
+- (void)createResponseWithStreamOrThrow: (OFStream *)stream
{
OFURL *URL = _request.URL;
OFHTTPClientResponse *response;
OFString *connectionHeader;
bool keepAlive;
OFString *location;
id exception;
- response = [[[OFHTTPClientResponse alloc] initWithSocket: sock]
+ response = [[[OFHTTPClientResponse alloc] initWithStream: stream]
autorelease];
response.protocolVersionString = _version;
response.statusCode = _status;
response.headers = _serverHeaders;
@@ -325,11 +326,11 @@
}
if (keepAlive) {
response.of_keepAlive = true;
- _client->_socket = [sock retain];
+ _client->_stream = [stream retain];
_client->_lastURL = [URL copy];
_client->_lastWasHEAD =
(_request.method == OFHTTPRequestMethodHead);
_client->_lastResponse = [response retain];
}
@@ -429,14 +430,14 @@
withObject: response
withObject: exception
afterDelay: 0];
}
-- (void)createResponseWithSocket: (OFTCPSocket *)sock
+- (void)createResponseWithStream: (OFStream *)stream
{
@try {
- [self createResponseWithSocketOrThrow: sock];
+ [self createResponseWithStreamOrThrow: stream];
} @catch (id e) {
[self raiseException: e];
}
}
@@ -471,11 +472,11 @@
_status = (short)status;
return true;
}
-- (bool)handleServerHeader: (OFString *)line socket: (OFTCPSocket *)sock
+- (bool)handleServerHeader: (OFString *)line stream: (OFStream *)stream
{
OFString *key, *value, *old;
const char *lineC, *tmp;
char *keyC;
@@ -490,14 +491,14 @@
[_client->_delegate client: _client
didReceiveHeaders: _serverHeaders
statusCode: _status
request: _request];
- sock.delegate = nil;
+ stream.delegate = nil;
- [self performSelector: @selector(createResponseWithSocket:)
- withObject: sock
+ [self performSelector: @selector(createResponseWithStream:)
+ withObject: stream
afterDelay: 0];
return false;
}
@@ -532,11 +533,11 @@
[_serverHeaders setObject: value forKey: key];
return true;
}
-- (bool)stream: (OFStream *)sock
+- (bool)stream: (OFStream *)stream
didReadLine: (OFString *)line
exception: (id)exception
{
bool ret;
@@ -552,12 +553,11 @@
@try {
if (_firstLine) {
_firstLine = false;
ret = [self handleFirstLine: line];
} else
- ret = [self handleServerHeader: line
- socket: (OFTCPSocket *)sock];
+ ret = [self handleServerHeader: line stream: stream];
} @catch (id e) {
[self raiseException: e];
ret = false;
}
@@ -594,12 +594,11 @@
if (chunked || [headers objectForKey: @"Content-Length"] != nil) {
stream.delegate = nil;
OFStream *requestBody = [[[OFHTTPClientRequestBodyStream alloc]
- initWithHandler: self
- socket: (OFTCPSocket *)stream] autorelease];
+ initWithHandler: self stream: stream] autorelease];
if ([_client->_delegate respondsToSelector:
@selector(client:wantsRequestBody:request:)])
[_client->_delegate client: _client
wantsRequestBody: requestBody
@@ -608,23 +607,23 @@
[stream asyncReadLine];
return nil;
}
-- (void)handleSocket: (OFTCPSocket *)sock
+- (void)handleStream: (OFStream *)stream
{
/*
* As a work around for a bug with split packets in lighttpd when using
* HTTPS, we construct the complete request in a buffer string and then
* send it all at once.
*
- * We do not use the socket's write buffer in case we need to resend
+ * We do not use the streams's write buffer in case we need to resend
* the entire request (e.g. in case a keep-alive connection timed out).
*/
@try {
- [sock asyncWriteString: constructRequestString(_request)];
+ [stream asyncWriteString: constructRequestString(_request)];
} @catch (id e) {
[self raiseException: e];
return;
}
}
@@ -632,58 +631,95 @@
- (void)socket: (OFTCPSocket *)sock
didConnectToHost: (OFString *)host
port: (uint16_t)port
exception: (id)exception
{
- sock.delegate = self;
+ if (exception != nil) {
+ [self raiseException: exception];
+ return;
+ }
+ sock.canBlock = false;
+
+ if ([_client->_delegate respondsToSelector:
+ @selector(client:didCreateTCPSocket:request:)])
+ [_client->_delegate client: _client
+ didCreateTCPSocket: sock
+ request: _request];
+
+ if ([_request.URL.scheme caseInsensitiveCompare: @"https"] ==
+ OFOrderedSame) {
+ OFTLSStream *stream;
+ @try {
+ stream = [OFTLSStream streamWithStream: sock];
+ } @catch (OFNotImplementedException *e) {
+ [self raiseException:
+ [OFUnsupportedProtocolException
+ exceptionWithURL: _request.URL]];
+ return;
+ }
+
+ if ([_client->_delegate respondsToSelector:
+ @selector(client:didCreateTLSStream:request:)])
+ [_client->_delegate client: _client
+ didCreateTLSStream: stream
+ request: _request];
+
+ stream.delegate = self;
+ [stream asyncPerformClientHandshakeWithHost: _request.URL.host];
+ } else {
+ sock.delegate = self;
+ [self performSelector: @selector(handleStream:)
+ withObject: sock
+ afterDelay: 0];
+ }
+}
+
+- (void)stream: (OFTLSStream *)stream
+ didPerformClientHandshakeWithHost: (OFString *)host
+ exception: (id)exception
+{
if (exception != nil) {
[self raiseException: exception];
return;
}
- if ([_client->_delegate respondsToSelector:
- @selector(client:didCreateSocket:request:)])
- [_client->_delegate client: _client
- didCreateSocket: sock
- request: _request];
-
- [self performSelector: @selector(handleSocket:)
- withObject: sock
+ [self performSelector: @selector(handleStream:)
+ withObject: stream
afterDelay: 0];
}
- (void)start
{
OFURL *URL = _request.URL;
- OFTCPSocket *sock;
+ OFStream *stream;
/* Can we reuse the last socket? */
- if (_client->_socket != nil && !_client->_socket.atEndOfStream &&
+ if (_client->_stream != nil && !_client->_stream.atEndOfStream &&
[_client->_lastURL.scheme isEqual: URL.scheme] &&
[_client->_lastURL.host isEqual: URL.host] &&
(_client->_lastURL.port == URL.port ||
[_client->_lastURL.port isEqual: URL.port]) &&
(_client->_lastWasHEAD || _client->_lastResponse.atEndOfStream)) {
/*
- * Set _socket to nil, so that in case of an error it won't be
- * reused. If everything is successful, we set _socket again
+ * 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.
*/
- sock = [_client->_socket autorelease];
- _client->_socket = nil;
+ stream = [_client->_stream autorelease];
+ _client->_stream = nil;
[_client->_lastURL release];
_client->_lastURL = nil;
[_client->_lastResponse release];
_client->_lastResponse = nil;
- sock.delegate = self;
+ stream.delegate = self;
- [self performSelector: @selector(handleSocket:)
- withObject: sock
+ [self performSelector: @selector(handleStream:)
+ withObject: stream
afterDelay: 0];
} else
[self closeAndReconnect];
}
@@ -694,23 +730,18 @@
OFTCPSocket *sock;
uint16_t port;
OFNumber *URLPort;
[_client close];
+
+ sock = [OFTCPSocket socket];
if ([URL.scheme caseInsensitiveCompare: @"https"] ==
- OFOrderedSame) {
- if (OFTLSSocketClass == Nil)
- @throw [OFUnsupportedProtocolException
- exceptionWithURL: URL];
-
- sock = [[[OFTLSSocketClass alloc] init] autorelease];
+ OFOrderedSame)
port = 443;
- } else {
- sock = [OFTCPSocket socket];
+ else
port = 80;
- }
URLPort = URL.port;
if (URLPort != nil)
port = URLPort.unsignedShortValue;
@@ -722,20 +753,20 @@
}
@end
@implementation OFHTTPClientRequestBodyStream
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
- socket: (OFTCPSocket *)sock
+ stream: (OFStream *)stream
{
self = [super init];
@try {
OFDictionary OF_GENERIC(OFString *, OFString *) *headers;
OFString *transferEncoding, *contentLengthString;
_handler = [handler retain];
- _socket = [sock retain];
+ _stream = [stream retain];
headers = _handler->_request.headers;
transferEncoding = [headers objectForKey: @"Transfer-Encoding"];
_chunked = [transferEncoding isEqual: @"chunked"];
@@ -757,25 +788,23 @@
return self;
}
- (void)dealloc
{
- if (_socket != nil)
+ if (_stream != nil)
[self close];
[_handler release];
[super dealloc];
}
-- (size_t)lowlevelWriteBuffer: (const void *)buffer
- length: (size_t)length
+- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
- size_t requestedLength = length;
- size_t ret;
+ /* TODO: Use non-blocking writes */
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
/*
* We must not send a chunk of size 0, as that would end the body. We
* always ignore writing 0 bytes to still allow writing 0 bytes after
@@ -783,90 +812,80 @@
*/
if (length == 0)
return 0;
if (_atEndOfStream)
- @throw [OFWriteFailedException
- exceptionWithObject: self
- requestedLength: requestedLength
- bytesWritten: 0
- errNo: 0];
+ @throw [OFWriteFailedException exceptionWithObject: self
+ requestedLength: length
+ bytesWritten: 0
+ errNo: ENOTCONN];
if (_chunked)
- [_socket writeFormat: @"%zX\r\n", length];
+ [_stream writeFormat: @"%zX\r\n", length];
else if (length > _toWrite)
- length = (size_t)_toWrite;
+ @throw [OFOutOfRangeException exception];
- ret = [_socket writeBuffer: buffer length: length];
+ [_stream writeBuffer: buffer length: length];
if (_chunked)
- [_socket writeString: @"\r\n"];
-
- if (ret > length)
- @throw [OFOutOfRangeException exception];
+ [_stream writeString: @"\r\n"];
if (!_chunked) {
- _toWrite -= ret;
+ _toWrite -= length;
if (_toWrite == 0)
_atEndOfStream = true;
}
- if (requestedLength > length)
- @throw [OFWriteFailedException
- exceptionWithObject: self
- requestedLength: requestedLength
- bytesWritten: ret
- errNo: 0];
-
- return ret;
+ return length;
}
- (bool)lowlevelIsAtEndOfStream
{
return _atEndOfStream;
}
- (void)close
{
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_chunked)
- [_socket writeString: @"0\r\n\r\n"];
+ [_stream writeString: @"0\r\n\r\n"];
else if (_toWrite > 0)
@throw [OFTruncatedDataException exception];
- _socket.delegate = _handler;
- [_socket asyncReadLine];
+ _stream.delegate = _handler;
+ [_stream asyncReadLine];
- [_socket release];
- _socket = nil;
+ [_stream release];
+ _stream = nil;
[super close];
}
- (int)fileDescriptorForWriting
{
- return _socket.fileDescriptorForWriting;
+ return ((OFStream *)_stream)
+ .fileDescriptorForWriting;
}
@end
@implementation OFHTTPClientResponse
@synthesize of_keepAlive = _keepAlive;
-- (instancetype)initWithSocket: (OFTCPSocket *)sock
+- (instancetype)initWithStream: (OFStream *)stream
{
self = [super init];
- _socket = [sock retain];
+ _stream = [stream retain];
return self;
}
- (void)dealloc
{
- if (_socket != nil)
+ if (_stream != nil)
[self close];
[super dealloc];
}
@@ -900,30 +919,30 @@
}
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_atEndOfStream)
return 0;
if (!_hasContentLength && !_chunked)
- return [_socket readIntoBuffer: buffer length: length];
+ return [_stream readIntoBuffer: buffer length: length];
- if (_socket.atEndOfStream)
+ if (_stream.atEndOfStream)
@throw [OFTruncatedDataException exception];
/* Content-Length */
if (!_chunked) {
size_t ret;
if (length > (unsigned long long)_toRead)
length = (size_t)_toRead;
- ret = [_socket readIntoBuffer: buffer length: length];
+ ret = [_stream readIntoBuffer: buffer length: length];
if (ret > length)
@throw [OFOutOfRangeException exception];
_toRead -= ret;
@@ -935,11 +954,11 @@
/* Chunked */
if (_toRead == -2) {
char tmp[2];
- switch ([_socket readIntoBuffer: tmp length: 2]) {
+ switch ([_stream readIntoBuffer: tmp length: 2]) {
case 2:
_toRead++;
if (tmp[1] != '\n')
@throw [OFInvalidServerReplyException
exception];
@@ -955,11 +974,11 @@
return 0;
} else if (_toRead == -1) {
char tmp;
- if ([_socket readIntoBuffer: &tmp length: 1] == 1) {
+ if ([_stream readIntoBuffer: &tmp length: 1] == 1) {
_toRead++;
if (tmp != '\n')
@throw [OFInvalidServerReplyException
exception];
}
@@ -970,11 +989,11 @@
return 0;
} else if (_toRead > 0) {
if (length > (unsigned long long)_toRead)
length = (size_t)_toRead;
- length = [_socket readIntoBuffer: buffer length: length];
+ length = [_stream readIntoBuffer: buffer length: length];
_toRead -= length;
if (_toRead == 0)
_toRead = -2;
@@ -983,11 +1002,11 @@
void *pool = objc_autoreleasePoolPush();
OFString *line;
size_t pos;
@try {
- line = [_socket tryReadLine];
+ line = [_stream tryReadLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException exception];
}
if (line == nil)
@@ -997,14 +1016,14 @@
if (pos != OFNotFound)
line = [line substringToIndex: pos];
if (line.length < 1) {
/*
- * We have read the empty string because the socket is
+ * We have read the empty string because the stream is
* at end of stream.
*/
- if (_socket.atEndOfStream && pos == OFNotFound)
+ if (_stream.atEndOfStream && pos == OFNotFound)
@throw [OFTruncatedDataException exception];
else
@throw [OFInvalidServerReplyException
exception];
}
@@ -1035,41 +1054,42 @@
- (bool)lowlevelIsAtEndOfStream
{
if (_atEndOfStream)
return true;
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (!_hasContentLength && !_chunked)
- return _socket.atEndOfStream;
+ return _stream.atEndOfStream;
return _atEndOfStream;
}
- (int)fileDescriptorForReading
{
- if (_socket == nil)
+ if (_stream == nil)
return -1;
- return _socket.fileDescriptorForReading;
+ return ((OFStream *)_stream)
+ .fileDescriptorForReading;
}
- (bool)hasDataInReadBuffer
{
- return (super.hasDataInReadBuffer || _socket.hasDataInReadBuffer);
+ return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer);
}
- (void)close
{
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
_atEndOfStream = false;
- [_socket release];
- _socket = nil;
+ [_stream release];
+ _stream = nil;
[super close];
}
@end
@@ -1132,19 +1152,30 @@
didPerformRequest: request
response: response
exception: nil];
}
-- (void)client: (OFHTTPClient *)client
- didCreateSocket: (OFTCPSocket *)sock
- request: (OFHTTPRequest *)request
+- (void)client: (OFHTTPClient *)client
+ didCreateTCPSocket: (OFTCPSocket *)TCPSocket
+ request: (OFHTTPRequest *)request
+{
+ if ([_delegate respondsToSelector:
+ @selector(client:didCreateTCPSocket:request:)])
+ [_delegate client: client
+ didCreateTCPSocket: TCPSocket
+ request: request];
+}
+
+- (void)client: (OFHTTPClient *)client
+ didCreateTLSStream: (OFTLSStream *)TLSStream
+ request: (OFHTTPRequest *)request
{
if ([_delegate respondsToSelector:
- @selector(client:didCreateSocket:request:)])
- [_delegate client: client
- didCreateSocket: sock
- request: request];
+ @selector(client:didCreateTLSStream:request:)])
+ [_delegate client: client
+ didCreateTLSStream: TLSStream
+ request: request];
}
- (void)client: (OFHTTPClient *)client
wantsRequestBody: (OFStream *)body
request: (OFHTTPRequest *)request
@@ -1255,15 +1286,15 @@
objc_autoreleasePoolPop(pool);
}
- (void)close
{
- [_socket release];
- _socket = nil;
+ [_stream release];
+ _stream = nil;
[_lastURL release];
_lastURL = nil;
[_lastResponse release];
_lastResponse = nil;
}
@end
Index: src/OFHTTPCookie.h
==================================================================
--- src/OFHTTPCookie.h
+++ src/OFHTTPCookie.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHTTPCookie.m
==================================================================
--- src/OFHTTPCookie.m
+++ src/OFHTTPCookie.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHTTPCookieManager.h
==================================================================
--- src/OFHTTPCookieManager.h
+++ src/OFHTTPCookieManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHTTPCookieManager.m
==================================================================
--- src/OFHTTPCookieManager.m
+++ src/OFHTTPCookieManager.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHTTPRequest.h
==================================================================
--- src/OFHTTPRequest.h
+++ src/OFHTTPRequest.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -107,17 +107,10 @@
*
* @note The setter creates a copy of the remote address.
*/
@property OF_NULLABLE_PROPERTY (nonatomic) const OFSocketAddress *remoteAddress;
-/**
- * @brief Creates a new OFHTTPRequest.
- *
- * @return A new, autoreleased OFHTTPRequest
- */
-+ (instancetype)request;
-
/**
* @brief Creates a new OFHTTPRequest with the specified URL.
*
* @param URL The URL for the request
* @return A new, autoreleased OFHTTPRequest
@@ -129,10 +122,12 @@
*
* @param URL The URL for the request
* @return An initialized OFHTTPRequest
*/
- (instancetype)initWithURL: (OFURL *)URL;
+
+- (instancetype)init OF_UNAVAILABLE;
@end
#ifdef __cplusplus
extern "C" {
#endif
Index: src/OFHTTPRequest.m
==================================================================
--- src/OFHTTPRequest.m
+++ src/OFHTTPRequest.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -78,44 +78,36 @@
}
@implementation OFHTTPRequest
@synthesize URL = _URL, method = _method, headers = _headers;
-+ (instancetype)request
-{
- return [[[self alloc] init] autorelease];
-}
-
+ (instancetype)requestWithURL: (OFURL *)URL
{
return [[[self alloc] initWithURL: URL] autorelease];
}
-- (instancetype)init
+- (instancetype)initWithURL: (OFURL *)URL
{
self = [super init];
- _method = OFHTTPRequestMethodGet;
- _protocolVersion.major = 1;
- _protocolVersion.minor = 1;
-
- return self;
-}
-
-- (instancetype)initWithURL: (OFURL *)URL
-{
- self = [self init];
-
@try {
_URL = [URL 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
{
[_URL release];
[_headers release];
@@ -139,16 +131,15 @@
return NULL;
}
- (id)copy
{
- OFHTTPRequest *copy = [[OFHTTPRequest alloc] init];
+ OFHTTPRequest *copy = [[OFHTTPRequest alloc] initWithURL: _URL];
@try {
copy->_method = _method;
copy->_protocolVersion = _protocolVersion;
- copy.URL = _URL;
copy.headers = _headers;
copy.remoteAddress = self.remoteAddress;
} @catch (id e) {
[copy release];
@throw e;
Index: src/OFHTTPResponse.h
==================================================================
--- src/OFHTTPResponse.h
+++ src/OFHTTPResponse.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -22,11 +22,11 @@
@class OFArray OF_GENERIC(ObjectType);
/**
* @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h
*
- * @brief A class for representing an HTTP request reply as a stream.
+ * @brief A class for representing an HTTP request response as a stream.
*/
@interface OFHTTPResponse: OFStream
{
OFHTTPRequestProtocolVersion _protocolVersion;
short _statusCode;
@@ -33,42 +33,45 @@
OFDictionary OF_GENERIC(OFString *, OFString *) *_headers;
OF_RESERVE_IVARS(OFHTTPResponse, 4)
}
/**
- * @brief The protocol version of the HTTP request reply.
+ * @brief The protocol version of the HTTP request response.
*/
@property (nonatomic) OFHTTPRequestProtocolVersion protocolVersion;
/**
- * @brief The protocol version of the HTTP request reply as a string.
+ * @brief The protocol version of the HTTP request response as a string.
*/
@property (copy, nonatomic) OFString *protocolVersionString;
/**
- * @brief The status code of the reply to the HTTP request.
+ * @brief The status code of the response to the HTTP request.
*/
@property (nonatomic) short statusCode;
/**
- * @brief The headers of the reply to the HTTP request.
+ * @brief The headers of the response to the HTTP request.
*/
@property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *)
*headers;
/**
- * @brief The reply as a string, trying to detect the encoding.
+ * @brief Read the response as a string, trying to detect the encoding and
+ * falling back to the specified encoding if not detectable.
+ *
+ * @return The response as a string
*/
-@property (readonly, nonatomic) OFString *string;
+- (OFString *)readString;
/**
- * @brief Returns the reply as a string, trying to detect the encoding and
+ * @brief Rread the response as a string, trying to detect the encoding and
* falling back to the specified encoding if not detectable.
*
- * @return The reply as a string
+ * @return The response as a string
*/
-- (OFString *)stringWithEncoding: (OFStringEncoding)encoding;
+- (OFString *)readStringWithEncoding: (OFStringEncoding)encoding;
@end
#ifdef __cplusplus
extern "C" {
#endif
Index: src/OFHTTPResponse.m
==================================================================
--- src/OFHTTPResponse.m
+++ src/OFHTTPResponse.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -294,16 +294,16 @@
return [OFString stringWithFormat: @"%hhu.%hhu",
_protocolVersion.major,
_protocolVersion.minor];
}
-- (OFString *)string
+- (OFString *)readString
{
- return [self stringWithEncoding: OFStringEncodingAutodetect];
+ return [self readStringWithEncoding: OFStringEncodingAutodetect];
}
-- (OFString *)stringWithEncoding: (OFStringEncoding)encoding
+- (OFString *)readStringWithEncoding: (OFStringEncoding)encoding
{
void *pool = objc_autoreleasePoolPush();
OFString *contentType, *contentLengthString, *ret;
OFData *data;
Index: src/OFHTTPServer.h
==================================================================
--- src/OFHTTPServer.h
+++ src/OFHTTPServer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -62,11 +62,12 @@
*/
- (bool)server: (OFHTTPServer *)server
didReceiveExceptionOnListeningSocket: (id)exception;
/**
- * @brief This method is called when a client socket encountered an exception.
+ * @brief This method is called when a socket for a client encountered an
+ * exception.
*
* This can happen when the OFHTTPServer tries to properly close the
* connection. If no headers have been sent yet, it will send headers, and if
* chunked transfer encoding was used, it will send a chunk of size 0. However,
* if the other end already closed the connection before that, this will raise
@@ -91,13 +92,10 @@
OF_SUBCLASSING_RESTRICTED
@interface OFHTTPServer: OFObject
{
OFString *_Nullable _host;
uint16_t _port;
- bool _usesTLS;
- OFString *_Nullable _certificateFile, *_Nullable _privateKeyFile;
- const char *_Nullable _privateKeyPassphrase;
id _Nullable _delegate;
OFString *_Nullable _name;
OFTCPSocket *_Nullable _listeningSocket;
#ifdef OF_HAVE_THREADS
size_t _numberOfThreads, _nextThreadIndex;
@@ -119,46 +117,10 @@
* Setting this after @ref start has been called raises an
* @ref OFAlreadyConnectedException.
*/
@property (nonatomic) uint16_t port;
-/**
- * @brief Whether the HTTP server uses TLS.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property (nonatomic) bool usesTLS;
-
-/**
- * @brief The path to the X.509 certificate file to use for TLS.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *certificateFile;
-
-/**
- * @brief The path to the PKCS#8 private key file to use for TLS.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *privateKeyFile;
-
-/**
- * @brief The passphrase to decrypt the PKCS#8 private key file for TLS.
- *
- * @warning You have to ensure that this is in secure memory protected from
- * swapping! This is also the reason why this is not an OFString.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property OF_NULLABLE_PROPERTY (assign, nonatomic)
- const char *privateKeyPassphrase;
-
/**
* @brief The delegate for the HTTP server.
*/
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
id delegate;
Index: src/OFHTTPServer.m
==================================================================
--- src/OFHTTPServer.m
+++ src/OFHTTPServer.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -13,10 +13,11 @@
* file.
*/
#include "config.h"
+#include
#include
#include
#import "OFHTTPServer.h"
#import "OFArray.h"
@@ -26,11 +27,10 @@
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFNumber.h"
#import "OFSocket+Private.h"
#import "OFTCPSocket.h"
-#import "OFTLSSocket.h"
#import "OFThread.h"
#import "OFTimer.h"
#import "OFURL.h"
#import "OFAlreadyConnectedException.h"
@@ -226,12 +226,22 @@
@throw [OFNotOpenException exceptionWithObject: self];
if (!_headersSent)
[self of_sendHeaders];
- if (!_chunked)
- return [_socket writeBuffer: buffer length: length];
+ if (!_chunked) {
+ @try {
+ [_socket writeBuffer: buffer length: length];
+ } @catch (OFWriteFailedException *e) {
+ if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN)
+ return e.bytesWritten;
+
+ @throw e;
+ }
+
+ return length;
+ }
pool = objc_autoreleasePoolPush();
[_socket writeString: [OFString stringWithFormat: @"%zX\r\n", length]];
objc_autoreleasePoolPop(pool);
@@ -526,20 +536,27 @@
URL.scheme = @"http";
URL.host = _host;
if (_port != 80)
URL.port = [OFNumber numberWithUnsignedShort: _port];
- if ((pos = [_path rangeOfString: @"?"].location) != OFNotFound) {
- OFString *path, *query;
-
- path = [_path substringToIndex: pos];
- query = [_path substringFromIndex: pos + 1];
-
- URL.URLEncodedPath = path;
- URL.URLEncodedQuery = query;
- } else
- URL.URLEncodedPath = _path;
+ @try {
+ if ((pos = [_path rangeOfString: @"?"].location) !=
+ OFNotFound) {
+ OFString *path, *query;
+
+ path = [_path substringToIndex: pos];
+ query = [_path substringFromIndex: pos + 1];
+
+ URL.URLEncodedPath = path;
+ URL.URLEncodedQuery = query;
+ } else
+ URL.URLEncodedPath = _path;
+ } @catch (OFInvalidFormatException *e) {
+ objc_autoreleasePoolPop(pool);
+ [self sendErrorAndClose: 400];
+ return;
+ }
[URL makeImmutable];
request = [OFHTTPRequest requestWithURL: URL];
request.method = _method;
@@ -809,70 +826,10 @@
- (uint16_t)port
{
return _port;
}
-- (void)setUsesTLS: (bool)usesTLS
-{
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- _usesTLS = usesTLS;
-}
-
-- (bool)usesTLS
-{
- return _usesTLS;
-}
-
-- (void)setCertificateFile: (OFString *)certificateFile
-{
- OFString *old;
-
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- old = _certificateFile;
- _certificateFile = [certificateFile copy];
- [old release];
-}
-
-- (OFString *)certificateFile
-{
- return _certificateFile;
-}
-
-- (void)setPrivateKeyFile: (OFString *)privateKeyFile
-{
- OFString *old;
-
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- old = _privateKeyFile;
- _privateKeyFile = [privateKeyFile copy];
- [old release];
-}
-
-- (OFString *)privateKeyFile
-{
- return _privateKeyFile;
-}
-
-- (void)setPrivateKeyPassphrase: (const char *)privateKeyPassphrase
-{
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- _privateKeyPassphrase = privateKeyPassphrase;
-}
-
-- (const char *)privateKeyPassphrase
-{
- return _privateKeyPassphrase;
-}
-
#ifdef OF_HAVE_THREADS
- (void)setNumberOfThreads: (size_t)numberOfThreads
{
if (numberOfThreads == 0)
@throw [OFInvalidArgumentException exception];
@@ -897,25 +854,11 @@
@throw [OFInvalidArgumentException exception];
if (_listeningSocket != nil)
@throw [OFAlreadyConnectedException exception];
- if (_usesTLS) {
- OFTCPSocket *TLSSocket;
-
- if (OFTLSSocketClass == Nil)
- @throw [OFUnsupportedProtocolException exception];
-
- TLSSocket = [[OFTLSSocketClass alloc] init];
- _listeningSocket = TLSSocket;
-
- TLSSocket.certificateFile = _certificateFile;
- TLSSocket.privateKeyFile = _privateKeyFile;
- TLSSocket.privateKeyPassphrase = _privateKeyPassphrase;
- } else
- _listeningSocket = [[OFTCPSocket alloc] init];
-
+ _listeningSocket = [[OFTCPSocket alloc] init];
_port = [_listeningSocket bindToHost: _host port: _port];
[_listeningSocket listen];
#ifdef OF_HAVE_THREADS
if (_numberOfThreads > 1) {
Index: src/OFHTTPURLHandler.h
==================================================================
--- src/OFHTTPURLHandler.h
+++ src/OFHTTPURLHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHTTPURLHandler.m
==================================================================
--- src/OFHTTPURLHandler.m
+++ src/OFHTTPURLHandler.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHostAddressResolver.h
==================================================================
--- src/OFHostAddressResolver.h
+++ src/OFHostAddressResolver.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHostAddressResolver.m
==================================================================
--- src/OFHostAddressResolver.m
+++ src/OFHostAddressResolver.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2022 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFHuffmanTree.h
==================================================================
--- src/OFHuffmanTree.h
+++ src/OFHuffmanTree.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer